Apache POI中实现行自动调整高度

46

我正在使用Apache POI将值输入电子表格。这些值具有换行符,并且我已成功地使用以下代码:

CellStyle style = cell.getCellStyle()
style.setWrapText(true)
cell.setCellStyle(style)

很遗憾,虽然文本的换行是正确的,但有时行高不足以显示全部内容。我该如何确保行高始终正确?

11个回答

31
currentRow.setHeight((short)-1)

适用于XSSFCell和Excel 2013


1
令人震惊的是,这在NPOI(.NET实现)中也可以工作,并且在Excel 2013中正确打开。语法略有不同:row.Height = -1; - Tyler Forsythe
12
这个解决方案不适用于Ubuntu的LibreOffice 5.1.6.2版本和POI 3.17,但如果使用MS Excel打开文档,则可以使用。 - Oscar Pérez
确切地说,这是个好答案! - sadati boina

22
HSSFWorkbook workbook=new HSSFWorkbook();
HSSFSheet sheet =  workbook.createSheet("FirstSheet");  
HSSFRow rowhead=   sheet.createRow((short)0);
HSSFCellStyle style = workbook.createCellStyle();
style.setWrapText(true);
row.setRowStyle(style);
row.getCell(0).setCellStyle(style);

上述代码将生成动态行高。


8
style.setWrapText(true)就足够了。谢谢! - Rubens Mariuzzo
10
嗯...这行不通。至少在Ubuntu Linux上使用Libre Office不行。 - ed22
2
@ed22,对我也不起作用。同样的环境。 - mr.nothing
1
这是一个与Libre Office相关的问题。在MS Excel中正确打开电子表格。 - ed22
1
我还必须使用Libre Office,但它不能解决行高的问题。有没有办法让Libre Office显示更好的行高呢?我有一个字体稍大的单元格。Libre Office不会自动增加行高,而MS Office和Open Office会以良好的方式增加高度。 - Sky
显示剩余3条评论

5
我唯一能让它工作的方法是编写自己的实现来计算行高。现在该代码已发布为Taro项目,因此您可以使用它。它具有众多方便的方法,让您只需少量代码即可编写Excel文件。
如果您更喜欢将实现放入您自己的代码中,可以在SpreadsheetTab类中找到它。在其中部分位置,有一个autoSizeRow(int rowIndex)方法。它基本上迭代查找行并对于每个单元格查找文本行数,然后使用字体大小计算最佳单元格高度。然后将行高设置为最高单元格的高度。

2
注意:此方法仅适用于单元格值中包含“\n”的情况。您需要自行确定在哪里放置“\n”。如果没有,“\n”将不会被添加,该行将只有一行高度。 - Gideon

4
请参阅此链接,其中提供了一些代码来手动计算行的正确高度,基于列宽和单元格内容。我个人没有测试过它。下面也贴出方便查看:
// Create Font object with Font attribute (e.g. Font family, Font size, etc) for calculation
java.awt.Font currFont = new java.awt.Font(fontName, 0, fontSize);
AttributedString attrStr = new AttributedString(cellValue);
attrStr.addAttribute(TextAttribute.FONT, currFont);

// Use LineBreakMeasurer to count number of lines needed for the text
FontRenderContext frc = new FontRenderContext(null, true, true);
LineBreakMeasurer measurer = new LineBreakMeasurer(attrStr.getIterator(), frc);
int nextPos = 0;
int lineCnt = 0;
while (measurer.getPosition() < cellValue.length())
{
    nextPos = measurer.nextOffset(mergedCellWidth); // mergedCellWidth is the max width of each line
    lineCnt++;
    measurer.setPosition(nextPos);
}

Row currRow = currSht.getRow(rowNum);
currRow.setHeight((short)(currRow.getHeight() * lineCnt));

// The above solution doesn't handle the newline character, i.e. "\n", and only
// tested under horizontal merged cells.

最后一行必须使用 row.getHeightInPoints() 或 currSht.getDefaultRowHeightInPoints(),而不是 "getHeight()"。 - ed22

3
在我的情况下,一个稳健的解决方案是计算行数并将行高设置为默认行高的倍数:
int numberOfLines = cell.getStringCellValue().split("\n").length;
row.setHeightInPoints(numberOfLines*sheet.getDefaultRowHeightInPoints());

即使没有换行,您也可以获得此内容,因此这是毫无意义的。 - Enerccio

2
cell.getRow().setHeight((short) -1);

适用于Apache POI 3.9或更高版本中的HSSFCell


1

它适用于Excel 2010。 我将单元格长度限制为50个字符

    Row row = sheet.createRow(0);
    CellStyle style = workbook.createCellStyle();
    style.setWrapText(true);
    if (data.length() > 50) {
        for (int i = 1; i <= Math.abs(data.length() / 50); i++) {
            data = data.substring(0, i * 50) + "\n" + data.substring(i * 50);
        }
        Cell cell = row.createCell(0);
        row.setRowStyle(style);
        cell.setCellStyle(style);
        cell.setCellValue(data);
        sheet.autoSizeColumn(0);
    }

所以没有自动高度。 - Joaquín L. Robles

0

你不能直接调整单元格的高度。 但是你可以改变行的高度。

final HSSFSheet fs = wb.createSheet("sheet1");
final HSSFRow row0 = fs.createRow(0);
final HSSFCell cellA1 = row0.createCell(0);
row0.setHeight((short)700);

10
这不是自动调整大小(自适应大小),而是手动调整大小。 - lu_ko

-1

对我来说,行自适应大小很有效:

cell.getRow().setHeight((short)0);

这里的0用于计算自动高度。


2
这似乎不起作用。当我在Excel(2010)中打开时,该行的高度为零。 - GreenGiant
1
@GreenGiant,我不使用Windows和Excel。这个解决方案适用于OpenOffice。在Excel中为“合并”单元格自动设置行高度也是一个问题(需要宏来修复它)。 - Michael Kazarian
遗憾的是,这将把高度设置为零,即不可见。 - iroel
-1的值实际上对我起了作用。 - Sergey Karpushin

-1

解决“LibreOffice Calc”和“WPS Spreadsheet”合并单元格自动调整行高的问题。

在主文档右侧添加一列(在我的情况下是第32列)。 将所有具有相同文本的合并单元格设置为相同的宽度。 将样式WrapText设置为true。 将样式设置为Align Top。 复制将显示在合并单元格中的内容。 将该列设置为隐藏。 将行高设置为-1。

代码示例:

   private void applyRowHightWorkaroundForMergedCells(HSSFCell cell0) {
       HSSFSheet sheet = cell0.getSheet();
       HSSFRow row = cell0.getRow();
    
       String value = cell0.getStringCellValue();
       HSSFCell cell = row.createCell(32);
       sheet.setColumnWidth(32, 32000);
       cell.getCellStyle().setWrapText(true);
       cell.getCellStyle().setVerticalAlignment(VerticalAlignment.TOP);
       cell.setCellValue(value);
       sheet.setColumnHidden(32, true);
       row.setHeight((short) -1);
   }

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