Apache POI 技术问询:如何以科学计数法向Excel写入数字
解决Apache POI写入Excel科学计数格式报错的问题
我之前也碰到过一模一样的问题!当你用#0.00E0作为科学计数格式时,Excel打开报错且格式丢失,核心原因是XSSFWorkbook(对应.xlsx文件)和HSSFWorkbook(对应.xls文件)对自定义数据格式的处理逻辑存在差异。
问题根源
对于XSSFWorkbook,DataFormat.getFormat()方法只会检索Excel内置的格式模板。当你传入的#0.00E0不属于内置格式时,它不会自动创建新的自定义格式,反而会返回一个无效的格式索引。Excel读取到这个无效索引后,就会报错并丢失格式设置。
解决方案
针对XSSFWorkbook,你需要显式调用XSSFDataFormat.addFormat()方法来注册自定义格式。下面是修改后的完整可运行代码:
import java.io.FileOutputStream; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFDataFormat; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class Main { public static void main(String[] args) { try (Workbook wb = new XSSFWorkbook(); FileOutputStream fos = new FileOutputStream("out.xlsx")) { Sheet sheet = wb.createSheet(); Cell cell = sheet.createRow(0).createCell(0); CellStyle style = wb.createCellStyle(); // 针对XSSFWorkbook显式添加自定义科学计数格式 XSSFDataFormat xssfFormat = (XSSFDataFormat) wb.createDataFormat(); short formatIndex = xssfFormat.addFormat("#0.00E0"); style.setDataFormat(formatIndex); cell.setCellStyle(style); cell.setCellValue(Math.random()); wb.write(fos); } catch (Exception e) { e.printStackTrace(); } } }
通用兼容写法(支持XSSF和HSSF)
如果你的代码需要同时支持两种格式的Workbook,可以加个类型判断:
short formatIndex; if (wb instanceof XSSFWorkbook) { XSSFDataFormat xssfFormat = (XSSFDataFormat) wb.createDataFormat(); formatIndex = xssfFormat.addFormat("#0.00E0"); } else { // HSSFWorkbook可以直接用getFormat自动创建自定义格式 org.apache.poi.ss.usermodel.DataFormat format = wb.createDataFormat(); formatIndex = format.getFormat("#0.00E0"); } style.setDataFormat(formatIndex);
运行修改后的代码后,生成的Excel文件会正确显示类似3.78E-01的科学计数格式,打开时也不会再报错。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

