Excel 97-2003 (.xls) 中的单元格样式丢失或未显示
Cell style is lost or not displayed in Excel 97-2003 (.xls)
我正在使用 Apache POI 库将数据导出到 Excel。我已经尝试了所有最新版本(3.17、4.1.2 和 5.2.1)。
我对 Excel 97 (.xls) 格式的单元格样式有疑问。单元格样式在一定数量的列后以某种方式丢失(或不显示)。
这是我的示例代码:
private void exportXls() {
try (
OutputStream os = new FileOutputStream("test.xls");
Workbook wb = new HSSFWorkbook();) {
Sheet sh = wb.createSheet("test");
Row r = sh.createRow(0);
for (int i = 0; i < 50; i++) {
Cell c = r.createCell(i);
c.setCellValue(i + 1);
CellStyle cs = wb.createCellStyle();
cs.setFillBackgroundColor(IndexedColors.WHITE.index);
cs.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cs.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
c.setCellStyle(cs);
}
wb.write(os);
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
以及 MS 查看的结果 Excel 2019
Viewed by MS Excel
如您所见,style/format 在第 43 个单元格后丢失。
但是,当我通过 XLS Viewer Free(来自 Microsoft Store)或 Google Sheets(在线)等其他应用程序打开同一文件时,style/format 仍然存在并且显示良好。
Viewed by XLS Viewer Free
Viewed by Google Sheets
有人能告诉我这是怎么回事吗?
我的代码中是否遗漏了什么?
MS Excel 中是否有任何隐藏设置导致此问题?
谢谢。
使用 apache poi
为每个单元格创建单元格样式不是一个好主意。单元格样式存储在 Excel 中的工作簿级别。如果可能,工作表和单元格共享单元格样式。
而且所有 Excel 版本中不同单元格样式的最大数量都有限制。二进制 *.xls
的限制小于 OOXML *.xlsx
.
的限制
限制本身不能成为您获得结果的唯一原因。但似乎 Excel 对工作簿中 50 个完全相同的单元格样式不是很满意。这些都是内存浪费,因为所有 50 个单元格都共享相同的样式,因此只需要一种共享样式。
解决方案是:
在单元格创建循环之外的工作簿级别创建单元格样式,并且仅将样式设置到循环中的单元格。
示例:
private static void exportXlsCorrect() {
try (
OutputStream os = new FileOutputStream("testCorrect.xls");
Workbook wb = new HSSFWorkbook();) {
CellStyle cs = wb.createCellStyle();
cs.setFillBackgroundColor(IndexedColors.WHITE.index);
cs.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cs.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
Sheet sh = wb.createSheet("test");
Row r = sh.createRow(0);
for (int i = 0; i < 50; i++) {
Cell c = r.createCell(i);
c.setCellValue(i + 1);
c.setCellStyle(cs);
}
wb.write(os);
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
有时在创建单元格之前不可能知道所有可能需要的单元格样式。然后可以使用CellUtil。这有一个方法 CellUtil.setCellStyleProperties
可以为单元格设置特定的样式属性。只有在需要时,才会在工作簿级别创建新的单元格样式。如果已经存在,则使用当前的单元格样式。
示例:
private static void exportXlsUsingCellUtil() {
try (
OutputStream os = new FileOutputStream("testUsingCellUtil.xls");
Workbook wb = new HSSFWorkbook();) {
Sheet sh = wb.createSheet("test");
Row r = sh.createRow(0);
for (int i = 0; i < 50; i++) {
Cell c = r.createCell(i);
c.setCellValue(i + 1);
java.util.Map<java.lang.String,java.lang.Object> properties = new java.util.HashMap<java.lang.String,java.lang.Object>();
properties.put(org.apache.poi.ss.util.CellUtil.FILL_BACKGROUND_COLOR, IndexedColors.WHITE.index);
properties.put(org.apache.poi.ss.util.CellUtil.FILL_FOREGROUND_COLOR, IndexedColors.LIGHT_BLUE.getIndex());
properties.put(org.apache.poi.ss.util.CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);
org.apache.poi.ss.util.CellUtil.setCellStyleProperties(c, properties);
}
wb.write(os);
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
我正在使用 Apache POI 库将数据导出到 Excel。我已经尝试了所有最新版本(3.17、4.1.2 和 5.2.1)。
我对 Excel 97 (.xls) 格式的单元格样式有疑问。单元格样式在一定数量的列后以某种方式丢失(或不显示)。
这是我的示例代码:
private void exportXls() {
try (
OutputStream os = new FileOutputStream("test.xls");
Workbook wb = new HSSFWorkbook();) {
Sheet sh = wb.createSheet("test");
Row r = sh.createRow(0);
for (int i = 0; i < 50; i++) {
Cell c = r.createCell(i);
c.setCellValue(i + 1);
CellStyle cs = wb.createCellStyle();
cs.setFillBackgroundColor(IndexedColors.WHITE.index);
cs.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cs.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
c.setCellStyle(cs);
}
wb.write(os);
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
以及 MS 查看的结果 Excel 2019 Viewed by MS Excel
如您所见,style/format 在第 43 个单元格后丢失。
但是,当我通过 XLS Viewer Free(来自 Microsoft Store)或 Google Sheets(在线)等其他应用程序打开同一文件时,style/format 仍然存在并且显示良好。 Viewed by XLS Viewer Free Viewed by Google Sheets
有人能告诉我这是怎么回事吗?
我的代码中是否遗漏了什么?
MS Excel 中是否有任何隐藏设置导致此问题?
谢谢。
使用 apache poi
为每个单元格创建单元格样式不是一个好主意。单元格样式存储在 Excel 中的工作簿级别。如果可能,工作表和单元格共享单元格样式。
而且所有 Excel 版本中不同单元格样式的最大数量都有限制。二进制 *.xls
的限制小于 OOXML *.xlsx
.
限制本身不能成为您获得结果的唯一原因。但似乎 Excel 对工作簿中 50 个完全相同的单元格样式不是很满意。这些都是内存浪费,因为所有 50 个单元格都共享相同的样式,因此只需要一种共享样式。
解决方案是:
在单元格创建循环之外的工作簿级别创建单元格样式,并且仅将样式设置到循环中的单元格。
示例:
private static void exportXlsCorrect() {
try (
OutputStream os = new FileOutputStream("testCorrect.xls");
Workbook wb = new HSSFWorkbook();) {
CellStyle cs = wb.createCellStyle();
cs.setFillBackgroundColor(IndexedColors.WHITE.index);
cs.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cs.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
Sheet sh = wb.createSheet("test");
Row r = sh.createRow(0);
for (int i = 0; i < 50; i++) {
Cell c = r.createCell(i);
c.setCellValue(i + 1);
c.setCellStyle(cs);
}
wb.write(os);
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
有时在创建单元格之前不可能知道所有可能需要的单元格样式。然后可以使用CellUtil。这有一个方法 CellUtil.setCellStyleProperties
可以为单元格设置特定的样式属性。只有在需要时,才会在工作簿级别创建新的单元格样式。如果已经存在,则使用当前的单元格样式。
示例:
private static void exportXlsUsingCellUtil() {
try (
OutputStream os = new FileOutputStream("testUsingCellUtil.xls");
Workbook wb = new HSSFWorkbook();) {
Sheet sh = wb.createSheet("test");
Row r = sh.createRow(0);
for (int i = 0; i < 50; i++) {
Cell c = r.createCell(i);
c.setCellValue(i + 1);
java.util.Map<java.lang.String,java.lang.Object> properties = new java.util.HashMap<java.lang.String,java.lang.Object>();
properties.put(org.apache.poi.ss.util.CellUtil.FILL_BACKGROUND_COLOR, IndexedColors.WHITE.index);
properties.put(org.apache.poi.ss.util.CellUtil.FILL_FOREGROUND_COLOR, IndexedColors.LIGHT_BLUE.getIndex());
properties.put(org.apache.poi.ss.util.CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);
org.apache.poi.ss.util.CellUtil.setCellStyleProperties(c, properties);
}
wb.write(os);
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
}