Apache POI:autoSizeColumn() 带有文本旋转和换行

Apache POI: autoSizeColumn() with text rotation and wrap text

我正在使用准备好的 .xlsx 文件并以编程方式对其进行编辑。这是原文:

在我的代码中,我 autosize 列:

    XSSFSheet sheet = workbook.getSheetAt(0);

    sheet.getColumnStyle(COLUMN_H).setWrapText(true);
    System.out.println("COL " + sheet.getColumnStyle(COLUMN_H).getWrapText());  // it's 'true'
    
    sheet.autoSizeColumn(COLUMN_H);

最终结果如下所示:

我希望该列缩小到足以显示文本的所有行。

我使用的是 POI 库的 5.2.2 版。

这不是autosize的作用吗?有没有办法计算列的首选宽度并明确设置?

当我双击H列的右边框时,宽度设置正常。

是的,这就是 Sheet.autoSizeColumn 迄今为止的工作方式。它不能像 Excel 的 GUI 那样做,只是因为它没有相同的资源和可能性。 Excel 的 GUI 作为桌面应用程序运行,因此可以访问完整的内存和图形系统。 Apache POI 只能访问 Java JRE 获得的内存和存储在 Excel 文件中的数据。这还不足以做同样的事情,Excel GUI 可以做到。

为了能够 auto-size Excel 单元格的宽度,程序必须知道列中每个单元格的字体规格和富文本格式的文本内容,以计算所需的宽度文本。这就是 Apache POI 迄今为止的尝试。当您看到 Sheet.autoSizeColumn 只为少量行消耗了多少时间时,这已经足够昂贵了。此外,这需要访问字体和 GUI-classes,例如 Java AWT。这目前已经在某些 server-systems.

中造成问题

为了能够进一步考虑 wrap-text 情况而文本中没有明确的换行符或者当文本也被旋转时,还需要知道列中每一行的行高。 Apache POI 直到现在才考虑到这一点。这就是为什么 Sheet.autoSizeColumn 只有在文本中有明确的换行符并且文本没有旋转时才能正常工作。

下面的完整示例说明了这一点。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.util.SheetUtil;

public class ExcelAutoSizeColumn {

 public static void main(String args[]) throws Exception {
  //String testString = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";

  String testString = 
    "Lorem ipsum dolor sit amet,\n"
   +"consetetur sadipscing elitr,\n"
   +"sed diam nonumy eirmod tempor \n"
   +"invidunt ut labore et dolore \n"
   +"magna aliquyam erat,\n"
   +"sed diam voluptua. At vero eos \n"
   +"et accusam et justo duo dolores \n"
   +"et ea rebum. Stet clita kasd gubergren,\n"
   +"no sea takimata sanctus est Lorem\n"
   +"ipsum dolor sit amet.";

  String filePath = "./Excel.xlsx";
  String fontName = "Calibri";
  short fontSize = 11;
  //short rotation = 0;
  //short rowHeight = -1;  //-1 for auto height
  short rotation = 90;
  short rowHeight = 180*20;
  boolean italic = false;
  boolean bold = false;

  try ( Workbook workbook = new XSSFWorkbook();
        java.io.FileOutputStream out = new java.io.FileOutputStream(filePath)) {
            
   Font font = workbook.createFont();
   font.setFontHeightInPoints(fontSize);
   font.setFontName(fontName);
   font.setItalic(italic);
   font.setBold(bold);
   CellStyle style = workbook.createCellStyle();
   style.setFont(font);
   style.setWrapText(true);
   style.setRotation(rotation);

   Sheet sheet = workbook.createSheet();
   Row row = sheet.createRow(0);
   row.setHeight(rowHeight);
   Cell cell = row.createCell(0);
   cell.setCellValue(testString);
   cell.setCellStyle(style);
  
   double width = SheetUtil.getColumnWidth(sheet, 0, true);
   System.out.println(width);

   sheet.autoSizeColumn(0, true);

   workbook.write(out);
  }
 }
}

您可以在 https://bz.apache.org/bugzilla/buglist.cgi?list_id=201224&product=POI 中提交有关此问题的错误报告。但我怀疑它会很快被修复,因为它会大大增加该方法的耗时。