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<String[]> 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<String[]> lista = new ArrayList<>(); List<List<String[]>> titles = new ArrayList<>(); lista.add(arra0); lista.add(arra1); lista.add(arrb1); titles.add(lista); String[] arr11 = {"", "", "2", "1"}; List<String[]> 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<List<String[]>> titles, List<Map<String, Object>> 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((short) 15); // 第一行生成账单标题 Row row = null; int rowNumCount = 0 == sheet.getLastRowNum() ? 0 : sheet.getLastRowNum() + 2;//获得总行数 // 存储标题在Excel文件中的序号 Map<String, Integer> titleOrder = new HashMap<>(); for (int j = 0; j < titles.size(); j++) { List<String[]> 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<Map<String, Object>> iterator = values.iterator(); int index = rowNumCount + 1; // 行号 while (iterator.hasNext()) { index++; // 出去标题行,从第一行开始写 row = sheet.createRow(index); Map<String, Object> value = iterator.next(); for (Map.Entry<String, Object> 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<String[]> 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((short) 15); // 第一行生成账单标题 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(); }}如有疑问,欢迎留言讨论!
Java的POI的封装与应用的更多相关文章
- java的poi技术写Excel的Sheet
在这之前写过关于java读,写Excel的blog如下: Excel转Html java的poi技术读,写Excel[2003-2007,2010] java的poi技术读取Excel[2003-20 ...
- Java使用POI读取和写入Excel指南
Java使用POI读取和写入Excel指南 做项目时经常有通过程序读取Excel数据,或是创建新的Excel并写入数据的需求: 网上很多经验教程里使用的POI版本都比较老了,一些API在新版里已经废弃 ...
- java的poi技术读取Excel数据到MySQL
这篇blog是介绍java中的poi技术读取Excel数据,然后保存到MySQL数据中. 你也可以在 : java的poi技术读取和导入Excel了解到写入Excel的方法信息 使用JXL技术可以在 ...
- java的poi技术读,写Excel[2003-2007,2010]
在上一篇blog:java的poi技术读取Excel[2003-2007,2010] 中介绍了关于java中的poi技术读取excel的相关操作 读取excel和MySQL相关: java的poi技术 ...
- java的poi技术读取Excel[2003-2007,2010]
这篇blog主要是讲述java中poi读取excel,而excel的版本包括:2003-2007和2010两个版本, 即excel的后缀名为:xls和xlsx. 读取excel和MySQL相关: ja ...
- Java Struts2 POI创建Excel文件并实现文件下载
Java Struts2 POI创建Excel文件并实现文件下载2013-09-04 18:53 6059人阅读 评论(1) 收藏 举报 分类: Java EE(49) Struts(6) 版权声明: ...
- Java利用POI导入导出Excel中的数据
首先谈一下今天发生的一件开心的事,本着一颗android的心我被分配到了PB组,身在曹营心在汉啊!好吧,今天要记录和分享的是Java利用POI导入导出Excel中的数据.下面POI包的下载地 ...
- java使用poi读取ppt文件和poi读取excel、word示例
java使用poi读取ppt文件和poi读取excel.word示例 http://www.jb51.net/article/48092.htm
- Atitit. C# java 的api 目录封装结构映射总结
Atitit. C# java 的api 目录封装结构映射总结 C# java ref System.Reflection System.Type, java.lang.ref concurrent ...
随机推荐
- P2110 欢总喊楼记
题目描述 诗经有云: 关关雎鸠,在河之洲.窈窕淑女,君子好逑. 又是一个被风吹过的夏天--一日欢总在图书馆中自习,抬起头来,只见一翩跹女子从面前飘过,真是回眸一笑百媚生,六宫粉黛无颜色!一阵诗情涌上欢 ...
- Spring Boot中使用EhCache实现缓存支持
SpringBoot提供数据缓存功能的支持,提供了一系列的自动化配置,使我们可以非常方便的使用缓存.,相信非常多人已经用过cache了.因为数据库的IO瓶颈.一般情况下我们都会引入非常多的缓存策略, ...
- js之点击值发生变化
点击值发生变化,应用场景,比如像阿里云那样我通常密码是以******的形式存在,我必须要点击查看,它才会以明文显示. 在实际开发中,比如以智能门锁为例,安装门锁时,有个叫密码输入框的表单,这个是选填项 ...
- php后台+前端开发过程整理
一.PHP后台从数据库中获取数据 1. 建立数据库连接: //在本项目中封装了数据库的各种操作 $dbConn = $this->_createMysqlConn(); 2. 执行sql语句 $ ...
- 一个简单好用的http服务器
http-server 是一个简单的零配置命令行HTTP服务器, 基于 nodeJs. 如果你不想重复的写 nodeJs 的 web-server.js, 则可以使用这个. 安装 (全局安装加 -g) ...
- [NOIp2015]运输计划 (二分 $+$ 树上差分)
#\(\mathcal{\color{red}{Description}}\) \(Link\) 在一棵带有边权的树上,可以选择使一条边权为零.然后对于所有\(M\)条链,使其链长最大值最小. #\( ...
- Oracle 下马观花看redo
----------------------------------------- --Lerning Content :Oracle 下马观花看redo --Author :如人饮水冷暖自知 --版 ...
- L2-022 重排链表(链表)
题目: 给定一个单链表 L1→L2→⋯→Ln−1→Ln,请编写程序将链表重新排列为 Ln→L1→Ln−1→L2→⋯.例如:给定L为1→2→3→4→5→6 ...
- C 没得写的水文
引言 - 没得写 最近工作上需要处理事情很多(接手, 维稳, 危机), 还有深入读书计划也提上了日程. 为了每月水经验, 这里带大家写个 C 的多值返回吧 : ) #include <stdio ...
- springboot快速入门(二)——项目属性配置(日志详解)
一.概述 application.properties就是springboot的属性配置文件 在使用spring boot过程中,可以发现项目中只需要极少的配置就能完成相应的功能,这归功于spring ...