Java使用poi导出Excel之格式设置
2021/7/14 20:09:28
本文主要是介绍Java使用poi导出Excel之格式设置,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
最近接到一个需求,客户不满意原本导出的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<String> headers, List<Map<String, Object>> 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); // 创建表头样式 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 numeralStyle = workbook.createCellStyle(); numeralStyle.setBorderBottom(BorderStyle.THIN); numeralStyle.setBorderRight(BorderStyle.THIN); numeralStyle.setBorderLeft(BorderStyle.THIN); numeralStyle.setFont(dataSetFont); // 数据内容对齐方式:居右 numeralStyle.setAlignment(HorizontalAlignment.RIGHT); // 此处设置数据格式 XSSFDataFormat df = workbook.createDataFormat(); 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<String, Object> 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")) { // 带小数点的数字格式 cell.setCellStyle(numeralStyle); numeralStyle.setDataFormat(df.getFormat("0.00"));//保留两位小数点 cell.setCellValue(Double.parseDouble(value.toString())); } else if (dataType.endsWith("Integer") || dataType.endsWith("Long")) { // 整型数字格式 cell.setCellStyle(numeralStyle); numeralStyle.setDataFormat(df.getFormat("General"));//数据格式采用常规 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<String> headers = Arrays.asList("客户编号", "手机号", "姓名", "创建时间", "账户余额", "账户余额1", "账户余额2", "年龄"); List<Map<String, Object>> datas = new ArrayList<>(); Map<String, Object> 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 " + filename + " succeed!"); } public static String date2Str(Date date, String pattern) { if (null == date) return ""; SimpleDateFormat sdf = new SimpleDateFormat(pattern); return sdf.format(date); } }
项目跑起来本地测试一波看看效果:
好像没啥毛病,收。。。。球都么得,余额那几列的小数点位数好像不对啊!
回首撸代码,我设置了啊, 咋就没生效呢???
于是乎继续网上扒资料,各种说法都试一波:
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<String> headers, List<Map<String, Object>> 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<String, Object> 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<String> headers = Arrays.asList("客户编号", "手机号", "姓名", "创建时间", "账户余额", "账户余额1", "账户余额2", "年龄"); List<Map<String, Object>> datas = new ArrayList<>(); Map<String, Object> 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只能赋值一次,后面的赋值无效导致的。
虽然被这个小问题折磨了快一天了,心态都崩了好几次,但是好在最后找到原因了,解决问题的感觉真爽,崩的稀碎的心态有重新凝聚起来,比以前更强大了呢。。。
这篇关于Java使用poi导出Excel之格式设置的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27本地多文件上传的简单教程
- 2024-11-27低代码开发:初学者的简单教程
- 2024-11-27如何轻松掌握拖动排序功能
- 2024-11-27JWT入门教程:从零开始理解与实现
- 2024-11-27安能物流 All in TiDB 背后的故事与成果
- 2024-11-27低代码开发入门教程:轻松上手指南
- 2024-11-27如何轻松入门低代码应用开发
- 2024-11-27ESLint开发入门教程:从零开始使用ESLint
- 2024-11-27Npm 发布和配置入门指南
- 2024-11-27低代码应用课程:新手入门指南