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 ...
随机推荐
- jquery validation验证身份证号、护照、电话号码、email
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Spring-IOC MethodInvokingFactoryBean 类源码解析
MethodInvokingFactoryBean MethodInvokingFactoryBean的作用是,通过定义类和它的方法,然后生成的bean是这个方法的返回值,即可以注入方法返回值. Me ...
- Kubernetes 初探
一.容器: 1. 容器是运行一个或一组进程的方法,使得这些进程和主机上其他进程相隔离 2. 容器类似于虚拟机,但不同于虚拟机 容器 ...
- 基于swoole的聊天室模型
client.html: <!doctype html><html><head> <meta charset="utf-8"> &l ...
- kendo ui - MultiSelect 多选系列
kendo-ui 官网:https://www.telerik.com/documentation 初始化 grid: 引入文件: <link rel="stylesheet" ...
- [转]C结构体之位域(位段)
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构 ...
- Kafka设计解析(十七)Kafka 0.11客户端集群管理工具AdminClient
转载自 huxihx,原文链接 Kafka 0.11客户端集群管理工具AdminClient 很多用户都有直接使用程序API操作Kafka集群的需求.在0.11版本之前,kafka的服务器端代码(即添 ...
- psql: 致命错误: 对用户"user1"的对等认证失败
操作系统:Debian8 登录pg时可能会有提示错误: $ psql -U user1 -d exampledb psql: 致命错误: 对用户"user1"的对等认证失败 打开以 ...
- C++之指针指向二维数组
一维指针通经常使用指针表示,其指向的地址是数组第一元素所在的内存地址,例如以下 int ary[4][5]; int(*aryp)[5] = ary; 那么ary[4]相当于int(*aryp).下面 ...
- iOS开发网络篇—发送GET和POST请求(使用NSURLSession) - 转
说明: 1.该文主要介绍如何使用NSURLSession来发送GET请求和POST请求 2.本文将不再讲解NSURLConnection的使用,如有需要了解NSURLConnection如何发送请求. ...