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之格式设置的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程