使用OpenXmlSDK,如何选择/更新作为范围控制的单元格中的值?

时间:2011-12-08 16:45:46

标签: excel openxml-sdk

我甚至不确定我是否使用了正确的术语;我会根据需要更新问题和标题。

我正在使用OpenXmlSDK填充预先存在的Excel 2010 .xlsm文件 - 一个启用宏的工作表。

我可以很好地访问工作表和单元格。

但是,我无法弄清楚如何访问或更新单元格中的数据,该单元格是从另一个工作表中的某个范围获取其值的下拉控件。

它在工作表上标记为“H13”,然后右键单击>>格式控制显示

Input range: 'anotherWorksheet'!$N$3:$N$54
Cell link: 'anotherWorksheet'!$M$3

每当我尝试获取对此单元格的引用时,我找不到它 - 我得到null

我尝试了两种访问方法:

我甚至不确定我是否使用了正确的术语;我会根据需要更新问题和标题。

我正在使用OpenXmlSDK填充预先存在的Excel 2010 .xlsm文件 - 一个启用宏的工作表。

我可以很好地访问工作表和单元格。

但是,我无法弄清楚如何访问或更新单元格中的数据,该单元格是从另一个工作表中的某个范围获取其值的下拉控件。

它在工作表上标记为“H13”,然后右键单击>>格式控制显示

Input range: 'anotherWorksheet'!$N$3:$N$54
Cell link: 'anotherWorksheet'!$M$3

每当我尝试获取对此单元格的引用时,我找不到它 - 我得到null

我尝试了两种访问方法:

    // http://msdn.microsoft.com/en-us/library/ff921204.aspx
    private static Cell GetCell(Worksheet worksheet, string addressName)
    {
        return worksheet.Descendants<Cell>().Where(
          c => c.CellReference == addressName).FirstOrDefault();
    }

    // Given a worksheet, a column name, and a row index,
    // gets the cell at the specified column and
    // http://stackoverflow.com/questions/527028/open-xml-sdk-2-0-how-to-update-a-cell-in-a-spreadsheet
    private static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex)
    {
        Row row = GetRow(worksheet, rowIndex);

        if (row == null)
            return null;

        return row.Elements<Cell>().Where(c => string.Compare
               (c.CellReference.Value, columnName +
               rowIndex, true) == 0).FirstOrDefault();
    }

    // Given a worksheet and a row index, return the row.
    private static Row GetRow(Worksheet worksheet, uint rowIndex)
    {
        return worksheet.GetFirstChild<SheetData>().
          Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
    }

两者都为目标单元格null生成H13,但提供对周围单元格的引用(即“H12,H14,G13”

实际上,I13也会产生null,但该单元格中没有任何内容。但是,如果我无法获得参考,我怎么能用SDK填充它?这不是我的主要观点。

我将接收与下拉列表中的一个条目匹配的数据;我只需要实际填充/选择目标电子表格中的特定条目。

如何使用OpenXmlSDK执行此操作?我尝试过使用各种开源库,但似乎都没有支持.xslm文件(客户端提供的文件,不能以其他格式使用;宏必须在启动时执行等)。

虽然我正在使用C#,但由于我的问题是关于OpenXmlSDK,我会接受使用该框架的其他语言的答案。

1 个答案:

答案 0 :(得分:1)

简答:单元格不存在,因此null引用。

我创建了一个带有列表(下拉列表)的小工作表,DataValidation指向另一个工作表中的一系列单元格。

使用Open XML SDK 2.0 Productivity Tool反映文件我看到,而不是创建单元格并将其附加到工作表,而是创建了一个DataValidation(CellReference等于目标)。

    using X14 = DocumentFormat.OpenXml.Office2010.Excel;

    [....]

    X14.DataValidations dataValidations1 = new X14.DataValidations() { Count = (UInt32Value)1U };
    dataValidations1.AddNamespaceDeclaration("xm", "http://schemas.microsoft.com/office/excel/2006/main");

    X14.DataValidation dataValidation1 = new X14.DataValidation() { Type = DataValidationValues.List, AllowBlank = true, ShowInputMessage = true, ShowErrorMessage = true };

    X14.DataValidationForumla1 dataValidationForumla11 = new X14.DataValidationForumla1();
    Excel.Formula formula1 = new Excel.Formula();
    formula1.Text = "Lists!$A$1:$A$51";

    dataValidationForumla11.Append(formula1);
    Excel.ReferenceSequence referenceSequence1 = new Excel.ReferenceSequence();
    referenceSequence1.Text = "A1";

    dataValidation1.Append(dataValidationForumla11);
    dataValidation1.Append(referenceSequence1);

    dataValidations1.Append(dataValidation1);

除非工作表位置具有预设值,否则在运行时访问它时实际上不会是“单元格”。

回想起来,这是有道理的。但在视觉上,它看起来像一个细胞,所以它并不明显......

不是一个细胞: ceci n'est pas un cell

注意:如果从DataValidation中进行选择并保存,则单元格现在具有值,因此它存在:

是一个细胞: c'est bizarre, non?

当返回空引用时,可以通过创建新单元格并将其附加到目标行来解决此问题。

现在的困难在于需要引用共享字符串表的验证,并且不接受原始文本作为单元格值....

更新:我能够找到与单元格关联的DataValidation,找到目标工作表和范围,找到该范围内的目标值,并获取与该值关联的SharedStringsTable引用。但无论我插入目标单元格的价值如何,Excel打开时都被认为是坏数据。

最后,我放弃了,回到Excel Interop,然后找到a method to select a dropdown field from within (ugh) Interop.