设置pageSetup时,OpenXML会破坏excel文件

时间:2016-11-23 10:54:40

标签: c# excel openxml

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

在DevExpress生成之后,我的文件如下所示: enter image description here

所以它有6页。我希望这样做而不是: enter image description here

为了在单独的表格上打印每个标签。

所以我使用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();
    }
}

但是在处理之后,当我尝试打开文件时出现错误"抱歉,我们发现某些内容存在问题[...]"。

你们有任何想法如何帮助我吗?

非常感谢!

2 个答案:

答案 0 :(得分: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添加到{{1}的末尾}}

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

答案 1 :(得分:0)

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);