最近接到一个需求,客户不满意原本导出的csv文件,想要导出Excel文件。不就导出Excel文件嘛,小意思,于是乎信心满满从网上扒导出的代码,一顿CV大法,搞定!代码如下:
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.xssf.usermodel.*;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
public class ExcelUtils {
// 新版Excel文件后缀
private static final String EXCEL_SUFFIX = ".xlsx";
/**
* 导出核心实现
*
* @param fileName
* @param headers
* @param dataList
* @return XSSFWorkbook
*/
@Deprecated
private static XSSFWorkbook writeDataToWorkbook(String fileName, List headers, List
项目跑起来本地测试一波看看效果:
好像没啥毛病,收。。。。球都么得,余额那几列的小数点位数好像不对啊!
于是乎继续网上扒资料,各种说法都试一波:
1.如下图加celltype的设置,测试效果和第一次一样,失败;
2.我又猜测是不是转double类型导致的,就改成如下图所示,赋值的时候用字符串格式:
测试效果和第一次一样,不,比第一次还差,小数位数不对就算了,单元格左上角多了个绿色的小箭头,意味着客户不能直接框选看总额了,失败;
这么简单个功能,我居然卡这里了,心态。。崩了啊。。。。
3. 是你逼我的。要出绝招了,我自己处理数据,于是改成这样:
跑起来,效果不错,小数位数都对了,但是单元格还是文本格式的。。。。
4. 数据格式都对了,单元格格式嘛,简单,设置下入参就好了,So easy!马上改成下图:
投降了。。我决定,文本格式就文本格式吧,数据格式对了就行,准备使用方案3了。
就在我要commit的时候,我突然看到结果4中的余额数据有","分割,我擦,这不是我设置的整型格式吗???我决定再试一把,我新建个数字格式专门给浮点型的数据用,代码又改成如下:
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.xssf.usermodel.*;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
public class ExcelUtils {
// 新版Excel文件后缀
private static final String EXCEL_SUFFIX = ".xlsx";
/**
* 导出核心实现
*
* @param fileName
* @param headers
* @param dataList
* @return XSSFWorkbook
*/
@Deprecated
private static XSSFWorkbook writeDataToWorkbook(String fileName, List headers, List> dataList) {
// 创建一个工作薄
XSSFWorkbook workbook = new XSSFWorkbook();
try {
// 创建一个工作表
XSSFSheet sheet = workbook.createSheet(fileName);
// 设置表头字体格式
XSSFFont headersFont = workbook.createFont();
headersFont.setColor(new XSSFColor(java.awt.Color.DARK_GRAY));
headersFont.setFontHeightInPoints((short) 14);
headersFont.setBold(true);
// 设置正文字体格式
XSSFFont dataSetFont = workbook.createFont();
dataSetFont.setColor(new XSSFColor(java.awt.Color.BLACK));
dataSetFont.setBold(false);
// 此处设置数据格式
XSSFDataFormat df = workbook.createDataFormat();
// 创建表头样式
XSSFCellStyle headersStyle = workbook.createCellStyle();
headersStyle.setBorderTop(BorderStyle.THIN);
headersStyle.setBorderBottom(BorderStyle.THIN);
headersStyle.setBorderLeft(BorderStyle.THIN);
headersStyle.setBorderRight(BorderStyle.THIN);
headersStyle.setFont(headersFont);
// 表头内容对齐方式:居中
headersStyle.setAlignment(HorizontalAlignment.CENTER);
// 创建文本样式
XSSFCellStyle textStyle = workbook.createCellStyle();
textStyle.setBorderBottom(BorderStyle.THIN);
textStyle.setBorderRight(BorderStyle.THIN);
textStyle.setBorderLeft(BorderStyle.THIN);
textStyle.setFont(dataSetFont);
// 数据内容对齐方式:居左
textStyle.setAlignment(HorizontalAlignment.LEFT);
// 创建浮点型数字样式
XSSFCellStyle floatStyle = workbook.createCellStyle();
floatStyle.setBorderBottom(BorderStyle.THIN);
floatStyle.setBorderRight(BorderStyle.THIN);
floatStyle.setBorderLeft(BorderStyle.THIN);
floatStyle.setAlignment(HorizontalAlignment.RIGHT);
floatStyle.setFont(dataSetFont);
floatStyle.setDataFormat(df.getFormat("#,##0.00"));
// 创建整型数字样式
XSSFCellStyle integerStyle = workbook.createCellStyle();
integerStyle.setBorderBottom(BorderStyle.THIN);
integerStyle.setBorderRight(BorderStyle.THIN);
integerStyle.setBorderLeft(BorderStyle.THIN);
integerStyle.setAlignment(HorizontalAlignment.RIGHT);
integerStyle.setFont(dataSetFont);
integerStyle.setDataFormat(df.getFormat("0"));
int index = 0;
// 创建表头并设置样式
XSSFRow row = sheet.createRow(index);
for (int i = 0; i < headers.size(); i++) {
sheet.setColumnWidth(i, 20 * 256);
XSSFCell cell = row.createCell(i);
cell.setCellStyle(headersStyle);
XSSFRichTextString text = new XSSFRichTextString(headers.get(i));
cell.setCellValue(text);
}
// 导出正文数据,并设置其样式
for (Map data : dataList) {
index++;
row = sheet.createRow(index);
int column = 0;
for (String key : data.keySet()) {
XSSFCell cell = row.createCell(column++);
Object value = data.get(key);
if (value == null) {
continue;
}
String dataType = value.getClass().getName();
if (dataType.endsWith("BigDecimal") || dataType.endsWith("Double") || dataType.endsWith("Float")) {
cell.setCellStyle(floatStyle); // 带小数点的数字格式
cell.setCellValue(Double.parseDouble(value.toString()));
} else if (dataType.endsWith("Integer") || dataType.endsWith("Long")) {
cell.setCellStyle(integerStyle); // 整型数字格式
cell.setCellValue(Double.parseDouble(value.toString()));
} else if (dataType.endsWith("Date")) {
cell.setCellStyle(textStyle); //日期转为字符串
cell.setCellValue(date2Str((Date) value, "yyyy-MM-dd HH:mm:ss"));
} else {
cell.setCellStyle(textStyle); // 文本格式
cell.setCellValue(value.toString());
}
}
}
} catch (Exception e) {
log.error("writeDataToWorkbook error, ", e);
}
return workbook;
}
/**
* 测试类
*/
public static void main(String[] args) {
String filename = date2Str(new Date(), "yyyyMMddHHmmss");
List headers = Arrays.asList("客户编号", "手机号", "姓名", "创建时间", "账户余额", "账户余额1", "账户余额2", "年龄");
List> datas = new ArrayList<>();
Map map = new LinkedHashMap<>();
map.put("id", 123);
map.put("mobile", "0833344545");
map.put("name", "jfdkdb ft#E@");
map.put("time", new Date());
map.put("amount", new BigDecimal("34276.8601"));
map.put("amount1", 34276.8);
map.put("amount2", 323455.10);
map.put("days", 24);
datas.add(map);
XSSFWorkbook wb = writeDataToWorkbook(filename, headers, datas);
try {
File file = new File("/Users/test/" + filename + EXCEL_SUFFIX);
FileOutputStream fileOutputStream = new FileOutputStream(file);
wb.write(fileOutputStream);
fileOutputStream.close();
} catch (Exception e) {
System.err.println(e.getMessage());
}
System.out.println("export excel succeed!");
}
public static String date2Str(Date date, String pattern) {
if (null == date) return "";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(date);
}
}
结果如下:
我擦嘞,真的就好了???!
原来是
XSSFCellStyle integerStyle = workbook.createCellStyle();
创建出来的style只能赋值一次,后面的赋值无效导致的。
虽然被这个小问题折磨了快一天了,心态都崩了好几次,但是好在最后找到原因了,解决问题的感觉真爽,崩的稀碎的心态有重新凝聚起来,比以前更强大了呢。。。