需要帮助将OpenXML dataValidation添加到现有Excel文件中

时间:2019-03-11 13:14:41

标签: c# excel openxml

我需要使用OpenXML dataValidation修改带有下拉列表的Excel文件。

由于某种原因,我可以使用下拉列表创建文件,但不能使用Open()方法添加1。

结果是一个没有下拉列表的空Excel文件。

这是我用来创建文件的方法:

public static void addCreateValidator(string path)
{
    using (SpreadsheetDocument myDoc = SpreadsheetDocument.Create(path, SpreadsheetDocumentType.Workbook))
    {

        WorkbookPart workbookpart = myDoc.AddWorkbookPart();
        workbookpart.Workbook = new Workbook();

        WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
        SheetData sheetData = new SheetData();

        worksheetPart.Worksheet = new Worksheet(sheetData);
        Sheets sheets = myDoc.WorkbookPart.Workbook.AppendChild(new Sheets());
        sheets.AppendChild(new Sheet()
        {
            Id = myDoc.WorkbookPart.GetIdOfPart(myDoc.WorkbookPart.WorksheetParts.First()),
            SheetId = 1,
            Name = "Sheet1"
        });

        DataValidations dataValidations = new DataValidations();
        DataValidation dataValidation = new DataValidation()
        {
            Type = DataValidationValues.List,
            AllowBlank = true,
            SequenceOfReferences = new ListValue<StringValue>() { InnerText = "A1:A1048576" }
        };
        Formula1 formula = new Formula1();
        formula.Text = "\"FirstChoice,SecondChoice,ThirdChoice\"";

        dataValidation.Append(formula);
        dataValidations.Append(dataValidation);

        worksheetPart.Worksheet.AppendChild(dataValidations);
    }
}

这是用于修改文件的方法:

public static void addValidation(string filepath)
    {
            using (SpreadsheetDocument myDoc = SpreadsheetDocument.Open(filepath, true))
            {

            WorkbookPart wbPart = myDoc.WorkbookPart;

            var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
            WorksheetPart worksheetPart =
                      GetWorksheetPartByName(myDoc, "Sheet1");

            DataValidations dataValidations = new DataValidations();
            DataValidation dataValidation = new DataValidation()
            {
                Type = DataValidationValues.List,
                AllowBlank = true,
                SequenceOfReferences = new ListValue<StringValue>() { InnerText = "h1" }
            };
            Formula1 formula = new Formula1();
            formula.Text = "\"FirstChoice,SecondChoice,ThirdChoice\"";

            dataValidation.Append(formula);
            dataValidations.Append(dataValidation);

            worksheetPart.Worksheet.AppendChild(dataValidations);
            //worksheetPart.Worksheet.Save();
        }


    }

您能看到任何错误或建议解决方法吗?

1 个答案:

答案 0 :(得分:0)

这是因为在现有文件中,您具有一些从头开始创建文件时没有的元素。

OpenXml文件的架构经常使用序列,因此元素的顺序很重要。在这种情况下,问题出在您的Worksheet中,架构是:

<xsd:complexType name="CT_Worksheet">
  <xsd:sequence>
    <xsd:element name="sheetPr" type="CT_SheetPr" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="dimension" type="CT_SheetDimension" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="sheetViews" type="CT_SheetViews" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="sheetFormatPr" type="CT_SheetFormatPr" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="cols" type="CT_Cols" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element name="sheetData" type="CT_SheetData" minOccurs="1" maxOccurs="1"/>
    <xsd:element name="sheetCalcPr" type="CT_SheetCalcPr" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="sheetProtection" type="CT_SheetProtection" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="protectedRanges" type="CT_ProtectedRanges" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="scenarios" type="CT_Scenarios" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="autoFilter" type="CT_AutoFilter" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="sortState" type="CT_SortState" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="dataConsolidate" type="CT_DataConsolidate" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="customSheetViews" type="CT_CustomSheetViews" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="mergeCells" type="CT_MergeCells" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="phoneticPr" type="CT_PhoneticPr" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="conditionalFormatting" type="CT_ConditionalFormatting" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element name="dataValidations" type="CT_DataValidations" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="hyperlinks" type="CT_Hyperlinks" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="printOptions" type="CT_PrintOptions" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="pageMargins" type="CT_PageMargins" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="pageSetup" type="CT_PageSetup" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="headerFooter" type="CT_HeaderFooter" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="rowBreaks" type="CT_PageBreak" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="colBreaks" type="CT_PageBreak" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="customProperties" type="CT_CustomProperties" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="cellWatches" type="CT_CellWatches" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="ignoredErrors" type="CT_IgnoredErrors" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="smartTags" type="CT_SmartTags" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="drawing" type="CT_Drawing" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="drawingHF" type="CT_DrawingHF" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="picture" type="CT_SheetBackgroundPicture" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="oleObjects" type="CT_OleObjects" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="controls" type="CT_Controls" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="webPublishItems" type="CT_WebPublishItems" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="tableParts" type="CT_TableParts" minOccurs="0" maxOccurs="1"/>
    <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  </xsd:sequence>
</xsd:complexType>

我怀疑最可能的罪魁祸首是PageMarginsDataValidations必须在PageMargins元素之前。您将DataValidations添加到末尾,默认情况下Excel将在新文件上写入PageMargins

假设它是PageMargins,下面的代码应该可以解决问题。

using (SpreadsheetDocument myDoc = SpreadsheetDocument.Open(filepath, true))
{
    WorkbookPart wbPart = myDoc.WorkbookPart;

    //var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
    WorksheetPart worksheetPart = GetWorksheetPartByName(myDoc, "Sheet1");

    DataValidations dataValidations = new DataValidations();
    DataValidation dataValidation = new DataValidation()
    {
        Type = DataValidationValues.List,
        AllowBlank = true,
        SequenceOfReferences = new ListValue<StringValue>() { InnerText = "A1:A1048576" }
    };
    Formula1 formula = new Formula1();
    formula.Text = "\"FirstChoice,SecondChoice,ThirdChoice\"";

    dataValidation.Append(formula);
    dataValidations.Append(dataValidation);

    //insert the dataValidations to the correct place
    worksheetPart.Worksheet.InsertBefore(dataValidations, worksheetPart.Worksheet.Descendants<PageMargins>().FirstOrDefault());
}

如果不是PageMargins,则可能是导致该问题的其他因素之一。 My answer here提供了解决此问题的方法,该方法稍微复杂一些但更可靠。