我正在使用 Apache POI,但遇到了一个奇怪的问题。我可以自动调整行的大小,但前提是该行中没有合并的单元格。这是一个例子:
new FileOutputStream('test.xlsx').withStream { OutputStream os ->
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
CellStyle wrapStyle = workbook.createCellStyle();
wrapStyle.setWrapText(true);
Row row = sheet.createRow(0); row.setRowStyle(wrapStyle);
Cell cell = row.createCell(0); cell.setCellStyle(wrapStyle);
cell.setCellValue("Very long text that needs to be wrapped")
cell = row.createCell(1); cell.setCellStyle(wrapStyle);
cell.setCellValue("Short text");
cell = row.createCell(2); cell.setCellStyle(wrapStyle);
cell.setCellValue("");
// These two lines break row auto-height!
//
CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 1, 2);
sheet.addMergedRegion(cellRangeAddress);
workbook.write(os);
}
这是一个错误吗?有谁知道解决方法吗?
最佳答案
经过更多研究,发现这是 Excel 本身的问题,而不是 POI 的问题。 Excel 确实失去了自动调整行以适应其中包含合并单元格的所有行的内容的能力。欲了解更多信息,请参阅:
http://excel.tips.net/T003207_Automatic_Row_Height_For_Merged_Cells_with_Text_Wrap.html http://blog.contextures.com/archives/2012/06/07/autofit-merged-cell-row-height/
解决方法是预测行最大单元格中的行数,然后手动调整行高。该代码基于此讨论:
http://mail-archives.apache.org/mod_mbox/poi-user/200906.mbox/%[email protected]%3E
下面的RowInfo
和 NestedCellInfo
是我的自定义数据结构,用于跟踪工作表布局。您应该能够将它们替换为您的等效函数和辅助函数。
private void adjustRowHeights(Sheet sheet, List<RowInfo> rows, SortedSet<Integer> createdColumnNumbers) {
SortedMap<Integer, Float> columnWidthsInPx = [] as TreeMap;
createdColumnNumbers.each {
columnWidthsInPx.put(it, sheet.getColumnWidthInPixels(it));
}
rows.each { RowInfo rowInfo ->
if ( rowInfo.hasMergedCells ) {
Row excelRow = sheet.getRow(rowInfo.rowIndex);
// Find the column with the longest text - that's the one that will determine
// the row height
//
NestedCellInfo longestCell = rowInfo.getCellWithLongestContent();
String cellText = longestCell.getText();
if ( cellText != null && cellText.size() > 5 ) {
int colIdx = rowInfo.cells.indexOf(longestCell);
// Figure out available width in pixels, taking colspans into account
//
float columnWidthInPx = columnWidthsInPx[colIdx];
int numberOfMergedColumns = longestCell.colSpan;
(numberOfMergedColumns - 1).times {
columnWidthInPx += columnWidthsInPx[colIdx + it];
}
// Setup the font we'll use for figuring out where the text will be wrapped
//
XSSFFont cellFont = longestCell.getCellFont();
int fontStyle = Font.PLAIN;
if ( cellFont.getBold() ) fontStyle = Font.BOLD;
if ( cellFont.getItalic() ) fontStyle = Font.ITALIC;
java.awt.Font currFont = new java.awt.Font(
cellFont.getFontName(),
fontStyle,
cellFont.getFontHeightInPoints());
AttributedString attrStr = new AttributedString(cellText);
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() < cellText.length()) {
nextPos = measurer.nextOffset( columnWidthInPx );
lineCnt++;
measurer.setPosition(nextPos);
}
if ( lineCnt > 1 ) {
excelRow.setHeight((short)(excelRow.getHeight() * lineCnt * /* fudge factor */ 0.7));
}
}
}
}
这个解决方案远非完美,但它让我能够继续前进。
关于java - Apache POI 和自动行高以及合并单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37744922/