我正在 java 中使用 Apache POI 创建一个 excel 文件。我填写数据,然后尝试自动调整每列的大小,但是大小总是错误的(并且我认为一致)。前两行总是(?)完全折叠。当我在 Excel 中自动调整列大小时,效果非常好。
没有写入空白单元格(我相信),调整大小是我做的最后事情。
这是相关代码:这是一个精简版本,没有错误处理等。
public static synchronized String storeResults(ArrayList<String> resultList, String file) {
if (resultList == null || resultList.size() == 0) {
return file;
}
FileOutputStream stream = new FileOutputStream(file);
//Create workbook and result sheet
XSSFWorkbook book = new XSSFWorkbook();
Sheet results = book.createSheet("Results");
//Write results to workbook
for (int x = 0; x < resultList.size(); x++) {
String[] items = resultList.get(x).split(PRIM_DELIM);
Row row = results.createRow(x);
for (int i = 0; i < items.length; i++) {
row.createCell(i).setCellValue(items[i]);
}
}
//Auto size all the columns
for (x = 0; x < results.getRow(0).getPhysicalNumberOfCells(); x++) {
results.autoSizeColumn(x);
}
//Write the book and close the stream
book.write(stream);
stream.flush();
stream.close();
return file;
}
我知道有一些类似的问题,但其中大多数只是在填写数据之前调整大小的情况。而少数没有的问题则更加复杂/没有答案。
编辑:我尝试使用几种不同的字体,但没有用。这并不奇怪,因为无论字体是什么,所有列都应该完全折叠,或者没有。
另外,因为出现了字体问题,所以我在 Windows 7 上运行该程序。
已解决:这是一个字体问题。我发现唯一有效的字体是 Serif。
只是为了根据我的评论做出答案。行的大小无法正确调整,因为 Java 不知道您尝试使用的字体。如果您想在 Java 中安装新字体,那么您可以使用更漂亮的字体,此链接应该会有所帮助。它还具有 Java 已知的默认字体列表。
很高兴这对您有所帮助,您的问题得到了解决!
我也遇到了这个问题,这就是我的解决方案。
步骤:
代码:
// initialize objects
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet spreadsheet = workbook.createSheet(sheetName);
XSSFRow row = spreadsheet.createRow(0);
XSSFCell cell;
// font/style
XSSFFont font = workbook.createFont();
font.setFontName("Arial");
XSSFCellStyle style = workbook.createCellStyle();
style.setFont(font);
// create/set cell & style
cell = row.createCell(0);
cell.setCellValue("New Cell");
cell.setCellStyle(style);
// auto size
spreadsheet.autoSizeColumn(0);
// create file
File aFile = new File("Your Filename");
FileOutputStream out = new FileOutputStream(aFile);
workbook.write(out);
资源:
这可能与 这个 POI Bug 有关,而该 POI Bug 又与 Java Bug JDK-8013716:自更新 45 以来,Calibri 和 Cambria 字体的渲染器失败有关。
在这种情况下,更改字体或使用 6u45 / 7u21 以上的 JRE 应该可以解决问题。
您还可以使用如下代码来解决问题并避免列完全折叠:
sheet.autoSizeColumn(x);
if (sheet.getColumnWidth(x) == 0) {
// autosize failed use MIN_WIDTH
sheet.setColumnWidth(x, MIN_WIDTH);
}
我在 Windows 7 上也遇到了类似的问题。
我使用的是 Calibri 字体(我的 JVM 支持该字体)。 使用该字体,
getBounds().getWidth()
POI 方法使用的 java.awt.font.TextLayout
的 autoSizeColumn()
返回 0。
将字体更改为 Calibri-Regular 解决了我的问题。
这是我的 2 美分 -
我使用默认字体(在我的例子中为 Arial),用它来使 xls 中的某些字段变为粗体。在 Windows 中与 autoSizeColumn() 函数一起工作就像一个魅力。
Linux 没有那么宽容。自动调整大小的某些地方不正确。经过这个线程和其他线程之后,我想出了以下解决方案。
我将 Arial 字体的 .tff 文件复制到 JAVA/jre/lib/fonts 目录中并重新运行应用程序。效果很好。
我曾使用 Helvetica 字体尝试替换 Arial 字体(事实上,Helvetica 与 Arial 类似)。
XSSFFont font = wb.createFont();
font.setFontName("Helvetica");
我发现当最宽的字符串以空格开头时,自动调整大小并没有使列足够宽,例如
cell.setCellValue(" New Cell");
这可以通过使用缩进来解决,例如
// font/style
XSSFFont font = workbook.createFont();
font.setFontName("Arial");
XSSFCellStyle style = workbook.createCellStyle();
style.setFont(font);
style.setIndention((short)2);
// create/set cell & style
cell = row.createCell(0);
cell.setCellValue("New Cell");
cell.setCellStyle(style);
// auto size
spreadsheet.autoSizeColumn(0);
以下内容对我有用。
我设置字体并在输入所有数据后使用autoSizeColumn()。
public static XSSFWorkbook createExcel(List<ChannelVodFileInfoList> resList) {
XSSFWorkbook hwb = new XSSFWorkbook();
String[] title = { "1", "2", "3", "4"};
XSSFSheet sheet = hwb.createSheet("dataStats");
XSSFRow firstrow = sheet.createRow(0);
for (int i = 0; i < title.length; i++) {
XSSFCell xh = firstrow.createCell(i);
xh.setCellValue(title[i]);
}
if (resList == null || resList.size() == 0) {
return hwb;
}
for (int i = 0; i < resList.size(); i++) {
ChannelVodFileInfoList doTemp = resList.get(i);
XSSFRow row = sheet.createRow(i + 1);
for (int j = 0; j < title.length; j++) {
XSSFCell cell = row.createCell(j);
Font font111 = hwb.createFont();
font111.setBoldweight(Font.BOLDWEIGHT_NORMAL);
XSSFCellStyle cellStyle111 = hwb.createCellStyle();
cellStyle111.setFont(font111);
cell.setCellStyle(cellStyle111);
if (j == 0) {
cell.setCellValue(dateStr);
} else if (j == 1) {
cell.setCellValue(doTemp.getChannelName());
}else if (j == 2) {
cell.setCellValue(doTemp.getBitrate());
}else if (j == 3) {
cell.setCellValue(doTemp.getWh());
}
}
for (int j = 0; j < title.length; j++) {
sheet.autoSizeColumn(j);
}
return hwb;
}
我的情况是自动调整大小后,这些单元格略小于实际内容的宽度。
我所做的只是在调用
autoSizeColumn
方法后添加了额外的 200 个宽度。
sheet.autoSizeColumn(columnIndex);
sheet.setColumnWidth(columnIndex, sheet.getColumnWidth(columnIndex) + 200);
这对我来说效果很好:)
如果用户遇到问题,他们有一张包含单元格和合并单元格的工作表,Gagravarr 在这篇文章中的回答确实对我有帮助:
https://stackoverflow.com/a/31425163/9407809
在此发布以供未来寻找此内容的用户使用。
这是对我有用的唯一方法:
在创建我写的任何内容之前:
for (int i = 0; i < columns.size(); i++)
sheet.trackColumnForAutoSizing(i);
创建工作表、列并插入数据后:
for (int i = 0; i < testata.size(); i++)
sheet.autoSizeColumn(i);
希望有帮助