新的一年,又一个开始,不见收获,却见年龄,好一个猪年,待我先来一首里尔克的诗:
《沉重的时刻》(里尔克)
此刻有谁在世上某处哭,无缘无故在世上哭,在哭我。
此刻有谁在夜间某处笑,无缘无故在夜间笑,在笑我。
此刻有谁在世上某处走,无缘无故在世上走,走向我。
此刻有谁在世上某处死,无缘无故在世上死,望着我。
不考虑以上所说的问题,个人花了些许时间写了两个Excel 工具类:ExcelReadUtil以及ExcelWriteUtil (代码地址见篇尾),集中处理了包含单不仅限于以下问题:
toXlsxByMap(List<Map<String,Object>> dataList,
String[] headerNames,
String[] cellNames,
CellFmt[] cellFmts)
导致的问题是传入的dataList内部的Map的value必须是Object类型,之后钻研了下java泛型,使用这种方式轻松解决问题!
public static <V extends Object> File toXlsxByMap(List<Map<String,V>> dataList,
String[] headerNames,
String[] cellNames,
CellFmt[] cellFmts)
//数据分组
List<List<Map<String, V>>> mData = splitMapList(dataList);
//循环每组数据 并创建sheet>写单元格
for (List<Map<String, V>> subList : mData) {
//第一个sheet 参数(sheet名称,sheet的序号)
sheet = workbook.createSheet(String.format("%s~%s",
(dataList.size() > DATA_SPLIT_GROP_SIZE ?
mData.indexOf(subList) * DATA_SPLIT_GROP_SIZE + 1
: 0) + "",
(dataList.size() > DATA_SPLIT_GROP_SIZE ?
(mData.size() == (mData.indexOf(subList) + 1) ? dataList.size() : DATA_SPLIT_GROP_SIZE * (mData.indexOf(subList) + 1))
: dataList.size()) + "")
);
LOGGER.info(">>>sheet name : {}",sheet.getSheetName());
PoiCellProcess.writeHeaderCell(sheet,headerCellStyle,headerNames);
PoiCellProcess.writeBodyCellByMap(sheet,bodyCellStyle,cellNames,subList, cellFmts);
}
public static CellStyle headerCellStyle(SXSSFWorkbook wb){
CellStyle headerStyle = wb.createCellStyle();
//...some code
//允许单元格内换行
headerStyle.setWrapText(true);
return headerStyle;
}
单元格类型及格式处理问题
这个问题其实分为多个,而且密切相关,大致有这几个:
- 单元格样式类
- 单元格样式类
- 单元格数据类型
- 单元格写入数据格式
但是,处理了这几个问题其实还不够完美
至于不完美的原因是什么呢,一个是Excel数据格式与java数据格式不一致(这个体现在日期,长数字,小数的处理上),比如你要格式化的日期后为“yyyy-mm-dd” 这种类型,
但是在Excel中相近的格式类型只有这样“yyyy/M/d”,如果强制单元格样式类型为“yyyy-mm-dd HH24:mi:ss” 其实也是可以的,只不过会变成自定义格式,而且是Excel的自定义格式,
具体如下图:
另外一个问题是单元格类型与编程语言的数据类型相异同时与poi所能提供的数据类型也相异,如图:
public static void writeHeaderCell(SXSSFSheet sheet, CellStyle headerCellStyle, String[] headerNames) {
SXSSFRow row = sheet.createRow(0);
row.setHeight((short) 30);
row.setHeightInPoints((short) 30);
SXSSFCell headerCell;
for (int i = 0; i < headerNames.length; i++) {
headerCell = row.createCell(i);
headerCell.setCellStyle(headerCellStyle);
headerCell.setCellValue(headerNames[i]);
sheet.setColumnWidth(i,
null == headerNames[i] ? CELL_BASE_LENGTH
: (headerNames[i].contains("\r\n") ? CELL_CHARSET_LENGTH * headerNames[i].length() / 2
: CELL_CHARSET_LENGTH * headerNames[i].length()));
}
}
这是最终处理的结果:以上写的过于粗糙,各位有更好的想法请分享下哈~
现在是 2019-02-18 星期一,各位中午好~
原文:https://www.cnblogs.com/funnyzpc/p/10392085.html