JAVA 使用 POI实现数据导出到Excel

前言:

    人生中第一次发布博客,怎么说还是有点紧张的。希望各位看官多多支持~~~JAVA 使用 POI实现数据导出到Excel

引入:

    就在上个礼拜,项目中有一个需求就是把一些数据导出到Excel中,并且要求Excel要按照规定的内容和排版显示导出来的数据。

    当时看到这个需求内心还是有点小压力的,毕竟刚刚做后台没多久(ps:我在外包公司,有什么就写什么。哈哈【Fuck!】)

    当然有压力还是没压力,该写还是要写的,我就开始上网查了一些关于 JAVA导出数据到Excel的一些相关文章 ,被一些只展示部分代码的那些自认为大佬的那些朋友们坑的不轻,展示的都是很简单的东西而且大家都会的,源码有的还有花钱才能下载!面对这些我决定自己研究研究,如果搞出来的话就免费发布出来,给大家提供方便或者解决一些大家出现的问题。

    还好,我搞出来了。

    说了一堆废话,讽刺一下那些大佬们。鼓励一下遇到问题没有找到合适答案的朋友们,多去研究咱们一样可以解决问题JAVA 使用 POI实现数据导出到Excel

进入主题:

    我使用的是JAVA POI实现的导出Excel。

    当然一看名字就知道是一个库或者是一个框架,那当然少不了jar包啦!

    第一步:这边因为需求是要用SpringBoot写,所以我使用了POM文件导入依赖,【如下图】

<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi</artifactId>
   <version>3.15</version>
</dependency>
<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml-schemas</artifactId>
   <version>3.15</version>
</dependency>
<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml</artifactId>
   <version>3.15</version>
</dependency>

    第二步:导入了依赖之后,切记不要着急,等待右下角提示导入依赖选择后才是真正的导入了POI的依赖!【如下图】

JAVA 使用 POI实现数据导出到Excel

        选择Import Changes 或者 Enable Auto-Import都可以,左边是每次修改依赖都需要手动去导入,右边是每次修改依赖之后自动导入,选择任意一个都可以!

    第三步:扩展一下知识点

        这里说一个小小的扩展:

            POI 提供了对2003版本的Excel的支持 ---- HSSFWorkbook

            POI 提供了对2007版本以及更高版本的支持 ---- XSSFWorkbook

            这个不用犯愁很好记: 2003版本的就记住一个H,2007以及更高版本的就记住一个X!

    第四步: 进入重头戏

        1、我们要拿到对应版本的对象,因为现在都是高本的的Excel,所以我使用了上面提到的 XSSFWorkbook       

XSSFWorkbook wb = new XSSFWorkbook();

        2、拿到了wb之后,我们就可以对Excel进行排版布局了,是不是有点小激动

        3、添加一个页

Sheet sheet = wb.createSheet("0");

        这一步我们实现的就是Excel打开之后左下角的那个Sheet,也就是当前页!

        4、开始设置Excel的排版样式【ps:具体样式根据项目需求来定,这里我举一个很大众化的布局】

            JAVA 使用 POI实现数据导出到Excel

        相信大多数的需求应该都和这个差不多吧,开始啦。

        【1】 拿到设置Excel表格样式的对象 CellStyle

        然后需要把我们最开始获取的那个wb传进来,就可以对单元格进行排版了。

        这里我提供一些最常用的样式:

        (单元格样式) 为什么只有后两条有注释呢,那是因为我相信聪明伶俐的你们都看得懂。。哈哈哈 border很明显边框嘛

CellStyle cellStyle = wb.createCellStyle();
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);

cellStyle.setTopBorderColor(HSSFColor.BLACK.index);
cellStyle.setBottomBorderColor(HSSFColor.BLACK.index);
cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
cellStyle.setRightBorderColor(HSSFColor.BLACK.index);

cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平居中
cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 上下居中

         (标题样式)    

XSSFFont titleFont = wb.createFont();
titleFont.setFontHeight(24);
titleFont.setBold(true);
CellStyle titleCellStyle = setCellStyle(wb);
titleCellStyle.setFont(titleFont);

        这里可以看到,在第四行我又创建了一个 CellStyle 那是因为标题需要加粗显示并且字体变大如果使用同一套样式,那么我相信,老板会对你产生怀疑JAVA 使用 POI实现数据导出到Excel

         (具体的标题实现 如下图)

/**
 * 主 标题 在这里插入主标题
 */
Row titleRow;
Cell titleCell;
sheet.addMergedRegion(new CellRangeAddress((short)0, (short)2, (short)0, (short)8));
for (int i = 0; i <= 2; i++) {
    titleRow = sheet.createRow(i);
    for (int j = 0; j < 9; j++) {
        titleCell = titleRow.createCell(j);
        titleCell.setCellType(CellType.STRING);
        titleCell.setCellStyle(titleCellStyle);
        titleCell.setCellValue("这里是大标题");
    }
}

        外面的那两个标题分别是创建一行和列

        第三行,就是合并单元格的操作,这里要记住Excel下标也是从0开始!

        注意看图中的CellType.STRING这个很重要,如果你不写你会发现你的样式根本不会生效!

        【有一个小扩展来了】

            因为Excel的每一个单元格是Cell类型,如同我们JAVA中的变量,如果你非要把 double 放入到 int 里面会出现什么情况?那么Excel也不例外,所以我们统一转换成String!

        然后使用循环去创建对应的单元格,并且要记得把你写好的样式加到每一个单元格里面。

          (数据展示)

        标题都会写了,那展示数据还有什么难的?

/**
 * 列 数据 在这里插入数据
 */
Row rowCheck;
Cell cellCheck;
for (int i = 3; i < 2000; i++) {
    rowCheck = sheet.createRow((i + 1));
    for (int j = 0; j < 9; j++) {
        cellCheck = rowCheck.createCell(j);
        cellCheck.setCellType(CellType.STRING);
        cellCheck.setCellStyle(cellStyle);
        cellCheck.setCellValue("测试 - 0" + (i - 2));
    }
}

        这里和标题的实现是一样的,切记一定把那个样式改了。。。。

           (最激动的时候到了 导出!!!)

try {
    File file = new File(exportPositionPath);
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    wb.write(fileOutputStream);
    fileOutputStream.close();
} catch (IOException e) {
    System.err.println(e.getMessage());
}

        其中File里面的参数就是你要导出文件的位置,也就是你要把Excel放到哪里,这里赠送你们一个桌面地址,哈哈哈。

//当前用户桌面
File desktopDir = FileSystemView.getFileSystemView()
        .getHomeDirectory();
String desktopPath = desktopDir.getAbsolutePath();
File file = new File(desktopPath + "\\这是生成的Excel表格.xlsx");

        对了差点忘记说一点,如果你的单个字段数据量比较大怎么办?

JAVA 使用 POI实现数据导出到Excel

        1、 让用户自己把单元格扩宽,查看详情

        2、我们固定一个最小宽度,是不是会更好一些?

Sheet sheet = wb.createSheet("0");
sheet.setColumnWidth(i, 4300);
        上面实现的就是拿到当前第一页的对象,然后给第一页的每一行设置最小宽度,4300并不是随便写的,其实他并不是很大,具体这个需要你们去测试,匹配适合自己的值,第一个参数 i 可能已经被猜到了吧,我用了一个循环而已,去循环每一行!

        【具体实现流程】

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class ZxExportExcel {

    /**
     * 生成Excel
     */
    public void zxExprotExcelXLSX() {
        XSSFWorkbook wb = new XSSFWorkbook();
        Sheet sheet = wb.createSheet("0");
        for (int i = 0; i < 9; i++) {
            sheet.setColumnWidth(i, 4300);
        }

        /**
         * 单元格 样式
         */
        CellStyle cellStyle = wb.createCellStyle();
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setTopBorderColor(HSSFColor.BLACK.index);
        cellStyle.setBottomBorderColor(HSSFColor.BLACK.index);
        cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
        cellStyle.setRightBorderColor(HSSFColor.BLACK.index);
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平居中
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 上下居中

        /**
         * 标题样式 样式
         */
        XSSFFont titleFont = wb.createFont();
        titleFont.setFontHeight(24);
        titleFont.setBold(true);
        CellStyle titleCellStyle = wb.createCellStyle();
        titleCellStyle.setBorderTop(BorderStyle.THIN);
        titleCellStyle.setBorderBottom(BorderStyle.THIN);
        titleCellStyle.setBorderLeft(BorderStyle.THIN);
        titleCellStyle.setBorderRight(BorderStyle.THIN);
        titleCellStyle.setTopBorderColor(HSSFColor.BLACK.index);
        titleCellStyle.setBottomBorderColor(HSSFColor.BLACK.index);
        titleCellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
        titleCellStyle.setRightBorderColor(HSSFColor.BLACK.index);
        titleCellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平居中
        titleCellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 上下居中
        titleCellStyle.setFont(titleFont);

        /**
         * 主 标题 在这里插入主标题
         */
        Row titleRow;
        Cell titleCell;
        sheet.addMergedRegion(new CellRangeAddress((short) 0, (short) 2, (short) 0, (short) 8));
        for (int i = 0; i <= 2; i++) {
            titleRow = sheet.createRow(i);
            for (int j = 0; j < 9; j++) {
                titleCell = titleRow.createCell(j);
                titleCell.setCellType(CellType.STRING);
                titleCell.setCellStyle(titleCellStyle);
                titleCell.setCellValue("2018年度能源科技进步奖");
            }
        }

        /**
         * 列 标题 在这里插入标题
         */
        Row rowLabel;
        Cell cellLabel;
        for (int i = 3; i < 4; i++) {
            rowLabel = sheet.createRow(i);
            for (int j = 0; j < 9; j++) {
                cellLabel = rowLabel.createCell(j);
                cellLabel.setCellType(CellType.STRING);
                cellLabel.setCellStyle(cellStyle);
                cellLabel.setCellValue("测试标题列【" + (j + 1) + "");
            }
        }

        /**
         * 列 数据 在这里插入数据
         */
        Row rowCheck;
        Cell cellCheck;
        for (int i = 3; i < 2000; i++) {
            rowCheck = sheet.createRow((i + 1));
            for (int j = 0; j < 9; j++) {
                cellCheck = rowCheck.createCell(j);
                cellCheck.setCellType(CellType.STRING);
                cellCheck.setCellStyle(cellStyle);
                cellCheck.setCellValue("测试 - 0" + (i - 2));
            }
        }

        /**
         * 页脚
         */
        setExcelFooterName("测试", 0, wb);

        /**
         * 进行导出
         */
        exportOutPutExcel("C:\\Users\\Admin\\Desktop\\ExportExcel.xlsx", wb);

    }

    /**
     * 设置Excel页脚
     */
    public void setExcelFooterName(String customExcelFooterName, int setExcelFooterNumber, XSSFWorkbook wb) {
        wb.setSheetName(setExcelFooterNumber, customExcelFooterName);
    }

    /**
     * 输出流 导出Excel到桌面
     */
    public void exportOutPutExcel(String exportPositionPath, XSSFWorkbook wb) {
        try {
            File file = new File(exportPositionPath);
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            wb.write(fileOutputStream);
            fileOutputStream.close();
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
    }

    public static void main(String[] args) {
        new ZxExportExcel().zxExprotExcelXLSX();
    }

}

        简单的使用了JAVA类去导出,仔细一看是不是很简单。

        过段时间出一个Excel导入的博客! 期待吧!!