NPOI C# 设置列宽自适应一页

5
我在我的C#应用程序中使用NPOI版本2.5.3,并尝试设置缩放选项(适合所有列到一页)。 从这些问题herehere中看来,这似乎很容易做到。 问题: 所以,当我使用下面的代码时出现了问题。 所有的配置都适合一页的宽度和高度。 我认为这是因为sheet.FitToPage = true造成的。
private void SetPrintSettings(XSSFSheet sheet)
{
    sheet.SetMargin(MarginType.BottomMargin, 0.5);
    sheet.SetMargin(MarginType.TopMargin, 0.5);
    sheet.SetMargin(MarginType.LeftMargin, 0.45);
    sheet.SetMargin(MarginType.RightMargin, 0.45);
    sheet.SetMargin(MarginType.HeaderMargin, 0.3);
    sheet.SetMargin(MarginType.FooterMargin, 0.3);

    sheet.Autobreaks = true; //auto breaks
    sheet.FitToPage = true;  //THIS SETS IT TO ALL FIT ON ONE PAGE

    var PrintSetup = sheet.PrintSetup;
    PrintSetup.FitWidth = 1; //fit width onto 1 page
    PrintSetup.FitHeight = 0; //don't care about height
    PrintSetup.Landscape = true;
    PrintSetup.PaperSize = 3; //paper size 11x17
}

当执行以上代码时,我在Excel中得到以下输出。

enter image description here

所以在那之后,我尝试将其设置为false,如下所示。
 private void SetPrintSettings(XSSFSheet sheet)
 {
    sheet.SetMargin(MarginType.BottomMargin, 0.5);
    sheet.SetMargin(MarginType.TopMargin, 0.5);
    sheet.SetMargin(MarginType.LeftMargin, 0.45);
    sheet.SetMargin(MarginType.RightMargin, 0.45);
    sheet.SetMargin(MarginType.HeaderMargin, 0.3);
    sheet.SetMargin(MarginType.FooterMargin, 0.3);

    sheet.Autobreaks = true; //auto breaks
    sheet.FitToPage = false; 

    var PrintSetup = sheet.PrintSetup;
    PrintSetup.FitWidth = 1; //fit width onto 1 page
    PrintSetup.FitHeight = 0; //don't care about height
    PrintSetup.Landscape = true;
    PrintSetup.PaperSize = 3; //paper size 11x17
}

当更改配置时,它会呈现如下所示的“无缩放”。

enter image description here

无论我尝试什么,似乎都无法让它起作用。我尝试了各种设置,但没有任何效果。我开始认为这可能是我使用版本的错误。几乎所有我找到的示例都是针对Java POI的,所以我不确定是否只是一个方法问题。
期望输出:
以下是我要做的事情。只需将缩放选项设置为适合1页的列即可。如果有人能帮助我或指点我方向,那就太棒了。

enter image description here


1
apache poi中,可以通过使用Sheet.setFitToPagePrintSetup.setFitWidthPrintSetup.setFitHeight的组合来设置。请参见https://dev59.com/Pp7ha4cB1Zd3GeqPkoY6#41856100。不确定`NPOI`是否使用相同的方法。 - Axel Richter
是的,这正是我所做的,但它没有以同样的方式工作。@Axel Richter - Selthien
2个回答

2

看起来这是 NPOI 中的一个 bug。

为了实现您想要的设置,您需要在工作表 XML 中的 PageSetup 元素中将 fitToHeight 属性设置为 0。例如:

<pageSetup orientation="landscape" fitToHeight="0"/>

很遗憾,如果我正确阅读了NPOI代码,那么它不会输出属性,因为它认为它是一个空值。
当您调用PrintSetup.FitHeight = 0;时,它会设置Sheet.cs中的fitToHeight属性。在写入文件时,在Sheet.cs中有以下内容:
XmlHelper.WriteAttribute(sw, "fitToHeight", this.fitToHeight, 1);

WriteAttribute 代码如下:

public static void WriteAttribute(StreamWriter sw, string attributeName, uint value, uint defaultValue, bool writeIfBlank = false)
{
    if(value != defaultValue)
        WriteAttribute(sw, attributeName, (int)value, writeIfBlank);
    else if(writeIfBlank)
        WriteAttribute(sw, attributeName, (int)value, writeIfBlank);
}

value (0) 不等于 defaultValue (1),因此我们进入第一个 if。这将调用另一个重载版本的WriteAttribute,其代码如下:

public static void WriteAttribute(StreamWriter sw, string attributeName, int value, bool writeIfBlank)
{
    if (value == 0 && !writeIfBlank)
        return;

    WriteAttribute(sw, attributeName, value.ToString(CultureInfo.InvariantCulture));
}

value 等于 0 并且 writeIfBlank 为 false,因此再次进入第一个 if,因此命中 return; 并且没有写出任何值。


0

1) 如果我理解正确,您可能会错过 autoSizeColumn。请配置/设置以自动调整列以适应您的需要,使用 youExcelSheet.AutoSizeColumn(),并且与页面/工作表的自适应组合 FitToPage 一起使用,这样应该可以为您工作。

源代码来自 Apache Github,由于列和页面大小的计算,调用顺序 可能autoSizeColautofit 页面之间很重要,您可以尝试两种组合 enter image description here

从Apache的参考文献中可以自动调整您的列大小,参见此处


// create some cells
for (int r=0; r < 10; r++) {
    Row row = sheet.createRow(r);
    for (int c; c < 10; c++) {
        Cell cell = row.createCell(c);
        cell.setCellValue("Cell " + c.getAddress().formatAsString());
    }
}


// 1 ** AUTO-Size the columns individually like below.
// 2 Or get/fit ALL, then loop through the cols, divide the sheet by number of cols


sheet.autoSizeColumn(0);
sheet.autoSizeColumn(1);

还有一个旧的示例在SO 这里

HSSFWorkbook spreadsheet = new HSSFWorkbook();

DataSet results = GetSalesDataFromDatabase();

//here, we must insert at least one sheet to the workbook. otherwise, Excel will say 'data lost in file'
HSSFSheet sheet1 = spreadsheet.CreateSheet("Sheet1");

foreach (DataColumn column in results.Tables[0].Columns)
{
    int rowIndex = 0;
    foreach (DataRow row in results.Tables[0].Rows)
    {
        HSSFRow dataRow = sheet1.CreateRow(rowIndex);
        dataRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());
        rowIndex++;
    }
    sheet1.AutoSizeColumn(column.Ordinal);
}

//Write the stream data of workbook to the file 'test.xls' in the temporary directory
FileStream file = new FileStream(Path.Combine(Path.GetTempPath(), "test.xls") , FileMode.Create);
spreadsheet.Write(file);
file.Close();

1
这与自动调整列宽无关,而是页面设置。虽然不相关,但我的列实际上是在此之前的代码中自动调整大小的。我正试图设置Excel表格的一个属性,即缩放选项。缩放选项需要设置为适合所有列占用一页。 - Selthien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接