Java的POI的封装与应用


Java对Excel表格的导出一直是对我有种可怕噩梦的东西,每次对要建立行与列,并一个一个放值,我是从心底拒绝的。

处于项目需求,需要导出表格,于是找到网上一版很好的开发, 《不想用POI?几行代码完成Excel导出导入》原文链接:  https://juejin.im/post/5c3b683ee51d4551d14175ee  

但是、我们项目不支持如此进行开发,

================================分割线=================================

因为需要引入xml文件进行开发,于是,只能自己动手封装一个满足需求的类:

一、需求:

查询统计的数据 List,进行数据导出,并且表头有合并单元格的需求。

直接上图:以下是部分结果(由于全部截取失真)

二、设计思路:

表头::把表头与数据插入表格对象进行分开。表头部分,每一行做为一个list, 使用String[]进行存储。每次分析表头,进行解析,生成表头。

表体::需要插入的数据使用list中存入 map对象,其中的对象字段名称与表头部分相同,就可以进行数据的插入。

代码如下:

/**  * Created by 闲一 on 2019/2/20.  */ package com.test;   import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.Test;   import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.*;   public class POItest2 {           @Test     public void test1() throws IOException {         List list = new ArrayList<>();         String[] arr = {"部门""云速"};         String[] arr1 = {"总计""10000000"};         String[] arr2 = {"单位""元"};         list.add(arr);         list.add(arr1);         list.add(arr2);         XSSFWorkbook workbook = new XSSFWorkbook();         workbook = workbookList(workbook, "come""", list);           String[] arra0 = {"name""名称""1""1"};         String[] arra1 = {"Person""人类""1""2"};         String[] arrb1 = {"Amions""动物""1""1"};         List lista = new ArrayList<>();         List> titles = new ArrayList<>();         lista.add(arra0);         lista.add(arra1);         lista.add(arrb1);         titles.add(lista);         String[] arr11 = {"""""2""1"};         List list1 = new ArrayList<>();         list1.add(arr11);         String[] arr21 = {"sex""性别""1""1"};         list1.add(arr21);         String[] arr31 = {"kaka""咳咳""1""1"};         list1.add(arr31);         String[] arr41 = {"kaka""小米""1""1"};         list1.add(arr41);         titles.add(list1);           workbook = workbookinList(workbook, "come""", titles, new ArrayList<>());         workbook = workbookinList(workbook, "come""", titles, new ArrayList<>());           String path = "d:/data/2019-02-19-04.csv";         wirteOutWorkbook(workbook, path);     }       /**      * 将数据写入指定Excel对象中      *      * @param workbook  Excel对象      * @param sheetName sheet名      * @param style     Excel类型      * @param titles    标题串 {{['person','人类',1,2]},      *                  {['name','名称',1,1], ['sex','性别',1,1]}}   【 字段名称,标题,所占行数,所占列数】      * @param values    内容集      * @return True\False      */     public XSSFWorkbook workbookinList(XSSFWorkbook workbook, String sheetName, String style, List> titles, List> values) {         // 生成一个表格         Sheet sheet;         sheet = workbook.getSheet(sheetName);         if (sheet == null) {             if (null == sheetName || "".equals(sheetName)) {                 sheet = workbook.createSheet(); // sheetName 为空则使用默认值             else {                 sheet = workbook.createSheet(sheetName);             }         }         // 设置表格默认列宽度为15个字节         sheet.setDefaultColumnWidth((short15);         // 第一行生成账单标题         Row row = null;         int rowNumCount = 0 == sheet.getLastRowNum() ? 0 : sheet.getLastRowNum() + 2;//获得总行数         // 存储标题在Excel文件中的序号         Map titleOrder = new HashMap<>();         for (int j = 0; j < titles.size(); j++) {             List list = titles.get(j);             row = sheet.createRow(rowNumCount + j);             int curCol = 0//当前列数名称             for (int i = 0; i < list.size(); i++) {                 org.apache.poi.ss.usermodel.Cell cell = row.createCell(curCol);                 String[] title = list.get(i);                 cell.setCellValue(title[1]); // 标题值                 // 需要记录每次的列位置                 int rowNum = Integer.valueOf(title[2]) - 1// 需要占用的行数                 int colNum = Integer.valueOf(title[3]) - 1// 需要占用的列数                 if (0 != rowNum || 0 != colNum) {                     int curRow = rowNumCount + j;                     CellRangeAddress region = new CellRangeAddress(curRow - rowNum, curRow, curCol, curCol + colNum);                     sheet.addMergedRegion(region);                     curCol += Integer.valueOf(title[3]);                 else {                     curCol++;                 }                 // 最后一行包含所有列                 if (j == titles.size() - 1) {                     titleOrder.put(title[0], i);                 }             }         }         /*          * 写入正文          */         Iterator> iterator = values.iterator();         int index = rowNumCount + 1// 行号         while (iterator.hasNext()) {             index++; // 出去标题行,从第一行开始写             row = sheet.createRow(index);             Map value = iterator.next();             for (Map.Entry map : value.entrySet()) {                 // 获取列名                 String title = map.getKey();                 // 根据列名获取序号                 Integer i = titleOrder.get(title);                 if (i == null) {                     continue;                 }                 // 在指定序号处创建cell                 Cell cell = row.createCell(i);                 // 获取列的值                 Object object = map.getValue();                 // 判断object的类型                 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");                 if (object instanceof Double) {                     cell.setCellValue((Double) object);                 else if (object instanceof Date) {                     String time = simpleDateFormat.format((Date) object);                     cell.setCellValue(time);                 else if (object instanceof Calendar) {                     Calendar calendar = (Calendar) object;                     String time = simpleDateFormat.format(calendar.getTime());                     cell.setCellValue(time);                 else if (object instanceof Boolean) {                     cell.setCellValue((Boolean) object);                 else {                     if (object == null) {                         cell.setCellValue("");                     else {                         cell.setCellValue(object.toString());                     }                 }             }         }         return workbook;     }       /**      * 将数据写入Excel文件中      *      * @param workbook  Excel对象      * @param sheetName sheet名      * @param style     Excel类型      * @param dataList  标题串+内容集 {{'部门','201930'},{'总计','10000万'}}      * @return True\False      */     public XSSFWorkbook workbookList(XSSFWorkbook workbook, String sheetName, String style, List dataList) {         // 生成一个表格         Sheet sheet;         sheet = workbook.getSheet(sheetName);         if (sheet == null) {             if (null == sheetName || "".equals(sheetName)) {                 sheet = workbook.createSheet(); // sheetName 为空则使用默认值             else {                 sheet = workbook.createSheet(sheetName);             }         }         // 设置表格默认列宽度为15个字节         sheet.setDefaultColumnWidth((short15);         // 第一行生成账单标题         Row row = null;         int rowNumCount = 0 == sheet.getLastRowNum() ? 0 : sheet.getLastRowNum() + 2;//获得总行数         // 存储标题在Excel文件中的序号         for (int i = 0; i < dataList.size(); i++) {             row = sheet.createRow(rowNumCount + i);             row.createCell(0).setCellValue(dataList.get(i)[0]);             row.createCell(1).setCellValue(dataList.get(i)[1]);         }         return workbook;     }       /**      * 文件写出      *      * @param workbook      * @param path      * @throws IOException      */     public void wirteOutWorkbook(XSSFWorkbook workbook, String path) throws IOException {         String dirPath = path.substring(0, path.lastIndexOf('.'));         File dirFile = new File(dirPath);         if (!dirFile.exists() && !dirFile.isDirectory()) {             dirFile.mkdirs();         }         File file = new File(path);         if (file.exists()) {             file.delete();         }         OutputStream outputStream = new FileOutputStream(file);         workbook.write(outputStream);         outputStream.close();         workbook.close();     } }

如有疑问,欢迎留言讨论!