excel导出文本格式设置为数值(easypoi)
文章目錄
- 場景
- 解決方案
- 設置type=10對不對
- 導出用到的主要元素和依賴關系
- 打造屬于自己的styler
- 錯誤的寫法
- 重新寫邏輯
- ExcelExportStatisticStyler 類完整的代碼
- setDataFormat有2種方式入參形式
- 解決總結
- setAlignment(HorizontalAlignment.CENTER) 報錯
- debug跟代碼一行一行看
- easypoi支持的自定義格式列表
場景
導出的數值單元格格式是文本。 客戶每次都要手動轉為數值,往往一個表格就是好多萬數據,轉換起來等半天。
解決方案
聽說@Excel 設置type=10即可。 實測無效。
設置type=10對不對
這樣設置是對的。 但是為什么沒有效果呢?
仔細跟代碼,發現type=10,會設置單元格的type為 Cell.CELL_TYPE_NUMERIC 。 單元格的值屬于CellValue ,和CelType都是屬于Cell 。
但是單元格屬性 屬于 CellStyle。
所以雖然值的輸出符合規范了,但是單元格顯示還是為文本。
導出用到的主要元素和依賴關系
使用easypoi 導出excel只用簡單的一個方法。
ExcelExportUtil.exportExcel(params, StatisticEntity.class, list);
主要元素列表如下:
| ExportParams | 定義導出的文件名,中文名,文件類型,導出樣式等。 |
| ExcelExportStatisticStyler | 繼承自ExcelExportStylerDefaultImpl類,定義樣式。 通過params.setStyle(ExcelExportStatisticStyler.class); 設置到ExportParams中。 如果不指定,默認使用ExcelExportStylerDefaultImpl |
| StatisticEntity | 導出單元格的實體,這里可以設置數據規則 |
打造屬于自己的styler
好的,既然ExportParams 可以setStyle,那么我們寫個類,繼承ExcelExportStylerDefaultImpl 重寫 getStyles方法不就成了么。
錯誤的寫法
思路,依照最小改動原則,先獲取已有的style,然后添加type=10的處理邏輯。代碼:
@Override public CellStyle getStyles2(boolean noneStyler, ExcelExportEntity entity) {CellStyle styles = super.getStyles(noneStyler, entity); // 獲取style// type=10 的處理if (entity != null && 10==entity.getType()) {styles.setDataFormat((short) BuiltinFormats.getBuiltinFormat("0.00"));return styles;}return styles; }測了下發現報錯, 是因為子類重寫getStyles()方法,super.getStyles()調的就是子類的getStyles()方法。 這不無限循環了么。
重新寫邏輯
代碼:
@Override public CellStyle getStyles(boolean noneStyler, ExcelExportEntity entity) {if (entity != null&& 10==entity.getType()) {return numberCellStyle;}return super.getStyles(noneStyler, entity); }實測成功。
導出的excel單元格格式為 自定義 0.00 。這還不是客戶要求的數值格式。但是只能做到這了。
至少我目前沒找到如何設置為數值格式。
ExcelExportStatisticStyler 類完整的代碼
public class ExcelExportStatisticStyler extends ExcelExportStylerDefaultImpl {private CellStyle numberCellStyle;public ExcelExportStatisticStyler(Workbook workbook) {super(workbook);createNumberCellStyler();}private void createNumberCellStyler() {numberCellStyle = workbook.createCellStyle();numberCellStyle.setAlignment(HorizontalAlignment.CENTER);numberCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);numberCellStyle.setDataFormat((short) BuiltinFormats.getBuiltinFormat("0.00"));numberCellStyle.setWrapText(true);}@Overridepublic CellStyle getStyles(boolean noneStyler, ExcelExportEntity entity) {if (entity != null&& 10==entity.getType()) {return numberCellStyle;}return super.getStyles(noneStyler, entity);} }setDataFormat有2種方式入參形式
1、字符串格式(推薦,可讀性更強)
2、_formats 數組的下標
兩種方式,本質上沒區別, 傳入string也是根據字面值,找_formats對應的下標。
見BuiltinFormats源碼 (強調 - 自定義格式一定要在_formats 數組內,否則無效):
兩種設置的例子:
// 使用字符串定義格式 cellStyle.setDataFormat((short) BuiltinFormats.getBuiltinFormat("0.00")); // BuiltinFormats._formats 數組中的下標 cellStyle.setDataFormat((short) 1);解決總結
步驟:
@Excel 中添加 type=10
寫個類繼承ExcelExportStylerDefaultImpl ,重寫getStyles()方法
導出前ExportParams。
既然重寫了getStyles(),那么其實type=10并不是唯一的辦法。
官網就是根據name中是否包含int,double等類型來判斷的,當然@Excel中的name要記得配合。(感覺type=10比改name更方便,更解耦)
setAlignment(HorizontalAlignment.CENTER) 報錯
版本的問題。 報錯代碼如下:
numberCellStyle.setAlignment(HorizontalAlignment.CENTER); numberCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);調整為如下代碼即可:
numberCellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); numberCellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);debug跟代碼一行一行看
ExcelExportBase類中的createCells方法中,如果類型為double,則進入如下邏輯:
else if (entity.getType() == BaseEntityTypeConstants.DoubleType) { }ExcelExportBase類中的createDoubleCell方法(type=10時設置了cellType):
public void createDoubleCell(Row row, int index, String text, CellStyle style,ExcelExportEntity entity) {Cell cell = row.createCell(index);if (text != null && text.length() > 0) {cell.setCellValue(Double.parseDouble(text));} else {cell.setCellValue(-1);}cell.setCellType(Cell.CELL_TYPE_NUMERIC); // 這里是設置了celltype為0,表示數字格式if (style != null) { // 這里設置stylecell.setCellStyle(style);}addStatisticsData(index, text, entity); }是不是type不影響頁面excel的文本格式,而是由style控制的呢。
easypoi支持的自定義格式列表
BuiltinFormats類的_formats列表里的自定義格式才有效,否則就會使用文本格式。
private final static String[] _formats = {"General","0","0.00","#,##0","#,##0.00","\"$\"#,##0_);(\"$\"#,##0)","\"$\"#,##0_);[Red](\"$\"#,##0)","\"$\"#,##0.00_);(\"$\"#,##0.00)","\"$\"#,##0.00_);[Red](\"$\"#,##0.00)","0%","0.00%","0.00E+00","# ?/?","# ??/??","m/d/yy","d-mmm-yy","d-mmm","mmm-yy","h:mm AM/PM","h:mm:ss AM/PM","h:mm","h:mm:ss","m/d/yy h:mm",// 0x17 - 0x24 reserved for international and undocumented// TODO - one junit relies on these values which seems incorrect"reserved-0x17","reserved-0x18","reserved-0x19","reserved-0x1A","reserved-0x1B","reserved-0x1C","reserved-0x1D","reserved-0x1E","reserved-0x1F","reserved-0x20","reserved-0x21","reserved-0x22","reserved-0x23","reserved-0x24","#,##0_);(#,##0)","#,##0_);[Red](#,##0)","#,##0.00_);(#,##0.00)","#,##0.00_);[Red](#,##0.00)","_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)","_(\"$\"* #,##0_);_(\"$\"* (#,##0);_(\"$\"* \"-\"_);_(@_)","_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)","_(\"$\"* #,##0.00_);_(\"$\"* (#,##0.00);_(\"$\"* \"-\"??_);_(@_)","mm:ss","[h]:mm:ss","mm:ss.0","##0.0E+0","@"};總結
以上是生活随笔為你收集整理的excel导出文本格式设置为数值(easypoi)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Gamma阶段]展示博客
- 下一篇: JVM深入理解