【问题标题】:OpenXML corrupts excel file when I set a pageSetup当我设置 pageSetup 时,OpenXML 损坏了 excel 文件
【发布时间】:2018-01-15 14:44:58
【问题描述】:

我有一个用 DevExpress 从我的程序中创建的 excel 文件。我需要在这个文件中添加水平分页,但我不能,因为我的 DevExpress 版本不能处理它。所以我在一个单独的类中使用 OpenXML 来检索生成的 excel 文件,以便将其添加到水平断页。

DevExpress 生成后,我的文件如下所示:

所以它有 6 页。我想要这个而不是:

为了在单独的工作表上打印每个选项卡。

所以我使用 openXML 中的 PageSetup 来定义我的 excel 文件的宽度和高度:

private void InsertPageBreaks()
{
    //uint columnIndex = 17U;
    uint rowIndex = 42;

    SpreadsheetDocument sd = SpreadsheetDocument.Open("c:\\temp\\ExcelExport1.xlsx", true);
    try
    {

        WorkbookPart workbookPart = sd.WorkbookPart;
        WorksheetPart worksheetPart = workbookPart.WorksheetParts.Last();

        // Uncomment the following line to insert row page breaks.
        InsertHorizontalPageBreak(rowIndex, worksheetPart);

        PageSetup pageSetup = new PageSetup() {FitToHeight = 2, FitToWidth = 1};
        worksheetPart.Worksheet.AppendChild(pageSetup);

    }
    finally
    {
        if (sd != null)
            ((IDisposable)sd).Dispose();
    }
}

但在处理后,当我尝试打开文件时,会显示错误“抱歉,我们发现某些内容存在问题 [...]”。

你们知道如何帮助我吗?

非常感谢!

【问题讨论】:

    标签: c# excel openxml


    【解决方案1】:

    如果没有看到文件很难判断,但我很确定这是因为您的元素的顺序而发生的。

    ECMA-376 standard 定义 Excel 文档的架构,其中一部分是 Worksheet 定义(第 3900 页)。定义太大,无法在此处完整粘贴,但有关 PageSetup 的部分如下所示:

    <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="2222 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"/>
    

    由于Worksheet 被定义为序列,因此顺序很重要。查看您的屏幕截图,您似乎有一个Header,它必须在PageSetup 之后,但您的代码将PageSetup 添加到Worksheet 的末尾。

    有关如何将项目添加到正确位置的示例,请参阅我对Why appending AutoFilter corrupts my excel file in this example?的回答

    【讨论】:

      【解决方案2】:

      OpenXML SDK 提供了一个名为 PageSetupProperties 的类,该类提供了一个名为 FitToPage 的属性。

      将此属性设置为 true 以选择单选按钮:

      SheetProperties _oPageSetupProperties = new SheetProperties(new PageSetupProperties());
      newWorksheetPart.Worksheet.SheetProperties = _oPageSetupProperties;
      
      // Set the FitToPage property to true
      newWorksheetPart.Worksheet.SheetProperties.PageSetupProperties.FitToPage = BooleanValue.FromBoolean(true);
      
      //set fitto width and height
      PageSetup pageSetup = new PageSetup();
      pageSetup.Orientation = OrientationValues.Landscape;
      pageSetup.FitToWidth = 1;
      pageSetup.FitToHeight = 50;
      newWorksheetPart.Worksheet.AppendChild(pageSetup);
      

      【讨论】:

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