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*/@Deprecatedprivate 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*/@Deprecatedprivate 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之格式设置相关推荐
- Java操作poi导出Excel自定义字体颜色
Java操作poi导出Excel自定义字体颜色 功能介绍 POI操作Excel 第一步创建一个导出的工具类 整体定义表格字体样式 自定义表格字体样式 总结 功能介绍 Apache POI 是用Java ...
- java利用poi导出excel功能-附带图片导出
java利用poi导出excel功能-附带图片导出 写在前面 最近刚离职,闲来无事,于是把上两家公司都有碰到过的需求但都没有去研究实现:即导出带图片的excel报表.于是就折腾了一下这个功能,研究出来 ...
- java中poi导出Excel表格(前台流文件接收)
java中poi导出Excel表格,前端以流的方式接收,而非直接生成文件再下载,解决多台服务器部署后,路径地址不统一导致的下载问题. 生成Excel示例图: 2.代码说明 ① 在上次的基础上增加了底部 ...
- Java和poi导出excel报表
一:poi jar下载地址:点击打开链接: 二:工程截图: 三:运行效果截图: 四:源代码: Student.java: package com.poi.bean;import java.util.D ...
- Java使用POi导出Excel(包含图片)
Java使用poi组件导出excel报表,能导出excel报表的还可以使用jxl组件,但jxl想对于poi功能有限,jxl应该不能载excel插入浮动层图片,poi能很好的实现输出excel各种功能, ...
- poi导出excel 损坏_急!!!java用poi导出excel文件,打开导出的文件时报错“文件错误,数据可能丢失”...
展开全部 两个原因: 1.你的excel模版本身有问题,可以尝试新建一个模版. 2.你的excel使用了一e68a8462616964757a686964616f31333365643662些POI不 ...
- java使用poi导出Excel表发回浏览器或是保存到本地
在实际工作中不可避免的会遇上统计.导出报表的工作,我自己整理了一份导出Excel代码放到这里,即为了分享知识,也是对自己的总结 首先导入依赖 <dependency><groupId ...
- java使用poi导出excel太慢
场景是查询数据然后导出excel,接口响应太慢. 处理接口慢,首先要找出哪个环节慢. 打日志看各环节花费时间,10W条数据 关联查询sql花费 3s,导出excel花费5S,响应传输时间很快不是关键问 ...
- java 使用poi导出excel,可控制固定前2列固定标头排版,带统计数据格式的
使用poi导出排版漂亮的excel文件 html代码: <button class="btn btn-link" ng-model="exportExcel&quo ...
- java通过poi导出excel和pdf
[背景] 由于各户的需求,所以需要增加导出excel这个功能,其实大部分系统都需要这个导出功能的,所以这里也就不详细说明具体导出的背景了O(∩_∩)O~ 干完导出excel将现有的导出pdf也进行了独 ...
最新文章
- xgb多线程成功运行记录
- widget模式弄不出来_【春天文化】互联网时代的教育模式培养精英
- mysql 引擎是表级别_Mysql表引擎优化
- ambari hdfs 启动报错_HDFS 运维常见问题处理
- virtual box中安装Mac OS后设置分辨率
- setuptools find_packages
- 从一片空白到世界领先,中国通信翻身逆袭史
- MySQL索引类型及优化
- 承认吧,你就是不行!
- 5、手把手教React Native实战之盒子模型BoxApp
- android信鸽推送demo_腾讯信鸽推送(java版)
- dos命令以及制作.bat文件
- MarkDown快捷教程
- silvaco AMS安装方法
- CTF-密码学-培根密码
- 微信小程序原生将两张图片合成一张并保存至手机中
- Convex Clustering(凸聚类)
- 系统安全——Windows中的共享文件和文件服务器
- 修改linux系统的root用户密码,linux系统下修改root用户密码
- 免费英文在线翻译-英文自动翻译
热门文章
- Fiddler4——手机抓包
- 用户启动计算机并登录win7,win7电脑设置开机登录界面的方法?
- android adb sdk下载地址,Android SDK 下载和安装
- linux下跑分软件下载,geekbench5下载-多平台综合性测试工具 v5.3.1 免费版 - 下载吧...
- 电脑常用的十款工具软件
- 黑群晖的网络录像机启用并直通互联网的几个关键点
- 软考-网络工程师复习资料
- Ubuntu16.04安装PyQt5教程(百度网盘)
- 层次分析法在高校教学评价体系中的应用(原理+实例+工具)
- 2020年CSDN技术人内推活动 千里马专区职位列表