【问题标题】:Creating cell comments in an Excel Spreadsheet with OpenXML SDK使用 OpenXML SDK 在 Excel 电子表格中创建单元格注释
【发布时间】:2010-10-10 04:22:52
【问题描述】:

我正在尝试将 cmets 添加到 Excel 2007 电子表格中的单元格。我正在使用 OpenXml SDK 2.0 来执行此操作。

我的用例是这样的: 我创建了一个模板 Excel 文件,我将其复制并用作起点,而不是从头开始创建 OpenXML 文档。我的模板文件在单元格 A1 中有注释,因此 Excel 已经为我创建了 WorksheetCommentPart。

现在我的问题是,当我将评论节点添加到评论部分时,电子表格不会加载,Excel 会询问我是否要恢复。

真正困扰我的是我在 A1 中的原始评论仍然存在,但我以编程方式添加的任何 cmets 都不见了!

这是我正在使用的代码:

使用 (MemoryStream 电子表格流 = 新的 MemoryStream()) { GetGradebookSpreadsheetTemplate(spreadsheetStream);

using (SpreadsheetDocument spDoc = SpreadsheetDocument.Open(spreadsheetStream, true))
{
    WorkbookPart wbPart = spDoc.WorkbookPart;
    WorksheetPart wsPart = wbPart.WorksheetParts.First();
    SheetData sheet = wsPart.Worksheet.GetFirstChild<SheetData>();
    Comments comments = wsPart.WorksheetCommentsPart.Comments;
    comments.Descendants<Author>().First().Text = string.Format("{0}, {1}", instructor.LastName, instructor.FirstName);
    comments.Descendants<Text>().First().Text = string.Format("{0}, {1}", instructor.LastName, instructor.FirstName);
    List<DefinedName> definedNames = new List<DefinedName>();
    definedNames.Add(CreateDefinedName("COLWeb_Gradebook", sheet.NamespaceURI, "Gradebook", "1", "A"));

    uint index = 4;
    foreach (User u in users)
        CreateUserDataRow(index++, definedNames, comments.CommentList, sheet, u, coursesForUsers[u], assignments, submissions[u]);
    Cell lastCell = sheet.Descendants<Cell>().Last();
    OpenXmlElement dimensionsElement = wsPart.Worksheet.Elements().Where(x => x.LocalName == "dimension").First();
    dimensionsElement.SetAttribute(new OpenXmlAttribute("ref", null, "A1:" + lastCell.CellReference));

    comments.Save();
    wsPart.Worksheet.Save();
    wbPart.Workbook.Save();
}

return spreadsheetStream.ToArray();

}

并且“CreateUserDataRow”创建了一个新行,但相关部分是(其中“comment”是我的评论字符串,“c”是我想要创建评论的单元格):

if (!string.IsNullOrEmpty(comment))
{
    List<OpenXmlElement> runs = new List<OpenXmlElement>();

    foreach (string row in comment.Split(new string[] { "<p>", "</p>" }, StringSplitOptions.RemoveEmptyEntries))
    {
        string trimmed = row.Trim();
        if (!string.IsNullOrEmpty(trimmed))
        {
            string escaped = System.Security.SecurityElement.Escape(trimmed);
            runs.Add(new Run(new RunProperties(), new Text(escaped)));
        }
    }

    Comment commentCell = new Comment();
    commentCell.Reference = c.CellReference;
    commentCell.AuthorId = 0;
    commentCell.AppendChild(new CommentText(runs));
    comments.AppendChild(commentCell);
}

现在,就我的眼睛和 KDiff3 而言,我的文件与我打开 Excel 并在 Excel 中手动将 cmets 放入单元格时输出的文件几乎相同。

有没有人有使用 OpenXml 将注释附加到单元格的好例子?关于一段关系,有什么我应该知道的吗?是否与使用我创建的 Excel 文件有关,然后我将其用作模板(可能某些尺寸未设置)?

感谢我能得到的任何帮助。

【问题讨论】:

    标签: c# excel comments openxml


    【解决方案1】:

    不幸的是,事情没那么简单。

    Cell cmets 也有一个图形对象,它位于 VML 绘图部分中。 VML 是一个神秘的遗留规范,不在批准的 ECMA 标准中。您可以在 Microsoft 的 Open XML 文档中找到有关它的文档,但它并不漂亮。希望 Microsoft 将在 Excel 14 中通过添加完整的单元格注释支持以及对也写入 VML 的控件的支持来解决此问题。

    话虽如此,我还没有使用过 Open XML SDK,也不能说是否可以使用它添加 cmets。我只是认为这可能会帮助您指出正确的方向。

    【讨论】:

    • 哎呀。好吧,至少我现在知道去哪里找了。虽然现在查看我的电子表格中包含的 VML 文件,但这是有道理的。谢谢。
    • 这是正确的。添加 cmets 需要添加 VML。另请注意,如果您添加 VML 并且没有像 Excel 那样完全对项目进行编号/标记,它将重新编号/重命名它们,这将随后损坏电子表格并崩溃 excel = Yuk!
    【解决方案2】:

    http://openxmldeveloper.org/forums/thread/7396.aspx 似乎有一个代码示例,它显示了如何创建必要的 VML 绘图。我现在正在尝试此代码,并且似乎已经取得了进展,尽管我仍然遇到某种未指明的错误,其中 Excel 决定在打开之前删除 cmets...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多