DrawingsPart 未添加到 WorksheetPart。指定的参数超出有效值范围

DrawingsPart not being added to the WorksheetPart. Specified argument was out of the range of valid values

使用 Open Xml SDK,我将 DrawingsPart 添加到 WorksheetPart,然后我尝试从 WorksheetPart 中引用 DrawingsPart但我收到 ArgumentOutOfRangeException.

这里是相关的代码片段:

// Add a new drawings part to the worksheet
var drawingsPart = worksheetPart.AddNewPart<DrawingsPart>();

// make a drawing DOM
var drawingRootElement = new WorksheetDrawing();

// add to the drawing DOM
...

// and then...
// associate the drawing DOM to the drawings part
drawingsPart.WorksheetDrawing = drawingRootElement;

// save the drawing DOM back to the drawings part
drawingsPart.WorksheetDrawing.Save();

// and finally...
// here is where it throws the ArgumentOutOfRangeException
// whether I supply the drawingsPart as the argument
// or the value worksheet.DrawingsPart
// it reports the same exception
// I looked up the source of OpenXmlPartContainer.GetIdOfPart
// and it looks like the DrawingsPart is not yet added to the
// PartDictionary of the WorksheetPart. I wonder why?
var relationshipIdOfDrawingsPart = drawingsPart
                            .GetIdOfPart(worksheetPart.DrawingsPart /* drawingsPart */);


// Create a new drawing element and add it to the Worksheet DOM
var drawingElement = new DocumentFormat.OpenXml.Spreadsheet.Drawing { Id = relationshipIdOfDrawingsPart };
worksheetPart.Worksheet.Append(drawingElement);

异常详情:

System.ArgumentOutOfRangeException occurred HResult=0x80131502
Message=Specified argument was out of the range of valid values.
Source=DocumentFormat.OpenXml StackTrace: at DocumentFormat.OpenXml.Packaging.OpenXmlPartContainer.GetIdOfPart(OpenXmlPart part) at ... my code

我查了一下OpenXmlPartContainer.GetIdOfPart的出处(转载如下):

// DocumentFormat.OpenXml.Packaging.OpenXmlPartContainer
/// <summary>
/// Gets the relationship ID of the part.
/// </summary>
/// <param name="part">The part.</param>
/// <returns>The relationship ID of the part.</returns>
/// <exception cref="T:System.ArgumentNullException">Thrown when "part" is null reference.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the part does not exist.</exception>
public string GetIdOfPart(OpenXmlPart part)
{
    this.ThrowIfObjectDisposed();
    if (part == null)
    {
        throw new ArgumentNullException("part");
    }
    if (this.PartDictionary.ContainsValue(part))
    {
        foreach (KeyValuePair<string, OpenXmlPart> current in this.PartDictionary)
        {
            if (part == current.Value)
            {
                return current.Key;
            }
        }
    }
    throw new ArgumentOutOfRangeException("part");
}

DrawingsPart 似乎没有添加到 WorksheetPartPartDictionary 中。我想知道为什么?

鉴于worksheetPart.DrawingsPartdrawingsPart是同一个对象,这段代码没有意义:

// and finally...
// here is where it throws the ArgumentOutOfRangeException
// whether I supply the drawingsPart as the argument
// or the value worksheet.DrawingsPart
// it reports the same exception
// I looked up the source of OpenXmlPartContainer.GetIdOfPart
// and it looks like the DrawingsPart is not yet added to the
// PartDictionary of the WorksheetPart. I wonder why?
var relationshipIdOfDrawingsPart = drawingsPart
                            .GetIdOfPart(worksheetPart.DrawingsPart /* drawingsPart */);

因为只有当对象的 PartDictionary 包含对 自身 .

的引用时才有效

因此,您需要在父对象上调用 GetIdOfPart,而不是 drawingsPart 本身。