一、背景

在后台项目中,经常会遇到将呈现的内容导出到Excel的需求,通过都是导出单个表头的Excel文件,如果存在级联关系的情况下,也就需要导出多表头的场景。今天这篇文章就是分享导出Excel单表头或多表头的实现,目前实现方案仅支持2行表头场景。如有更复杂的3行表头、4行表头复杂需求可以自行实现。

二、实现思路

1. 借助POI包实现表头的写入。每个表头其实就是一行,如果是多个表头,无非就是将写多行表头,然后将需要合并的表头进行合并,借助POI的函数为addMergedRegion。

2. 将导出数据进行转化为一个集合,循环写入每行数据。

三、实现代码

3.1 pom引入

1.8

3.17

1.3.2

org.springframework.boot

spring-boot-starter-aop

org.springframework.boot

spring-boot-starter-validation

org.mybatis.spring.boot

mybatis-spring-boot-starter

${mybatis.version}

mysql

mysql-connector-java

runtime

org.projectlombok

lombok

true

org.springframework.boot

spring-boot-starter-test

test

org.apache.poi

poi-ooxml

${poi.version}

org.apache.poi

poi

${poi.version}

View Code

3.2 Java代码实现

@Getter

@Setter

public class ExcelHelper {

/**

* 表格标题

*/

private String title;

/**

* 单元格宽度

*/

private int colWidth = 20;

/**

* 行高度

*/

private int rowHeight = 20;

private HSSFWorkbook workbook;

/**

* 表头样式

*/

private HSSFCellStyle headStyle;

/**

* 主体样式

*/

private HSSFCellStyle bodyStyle;

/**

* 日期格式化,默认yyyy-MM-dd HH:mm:ss

*/

private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

/**

* Constructor

* @param title

*/

public ExcelHelper(String title){

this.title = title;

workbook = new HSSFWorkbook();

init();

}

/**

* Constructor

* @param title

* @param colWidth

* @param rowHeight

*/

public ExcelHelper(String title, int colWidth, int rowHeight){

this.colWidth = colWidth;

this.rowHeight = rowHeight;

this.title = title;

workbook = new HSSFWorkbook();

init();

}

/**

* Constructor

* @param title

* @param colWidth

* @param rowHeight

* @param dateFormat

*/

public ExcelHelper(String title, int colWidth, int rowHeight, String dateFormat) {

this.title = title;

this.colWidth = colWidth;

this.rowHeight = rowHeight;

workbook = new HSSFWorkbook();

sdf = new SimpleDateFormat(dateFormat);

init();

}

/**

* 导出Excel,适用于web导出excel

*

* @param sheet

* @param data

*/

private void writeSheet(HSSFSheet sheet, List data,List headerList) {

try {

sheet.setDefaultColumnWidth(colWidth);

sheet.setDefaultRowHeightInPoints(rowHeight);

createHead(headerList, sheet);

writeSheetContent(headerList, data, sheet);

} catch (Exception e) {

throw new RuntimeException(e);

}

}

/**

* 导出表格

* @param listColumn

* @param datas

* @return

* @throws Exception

*/

public InputStream exportExcel(List listColumn,List datas) throws Exception {

splitDataToSheets(datas,listColumn);

return save(workbook);

}

/**

* 导出表格 支持2级表头或单表头的Excel导出

* @param headers

* @param datas

* @param filePath

* @throws FileNotFoundException

* @throws IOException

* void

*/

public void exportExcel(List headers,List datas,String filePath) throws IOException {

splitDataToSheets(datas, headers);

save(workbook, filePath);

}

/**

* 把数据写入到单元格

* @param listColumn

* @param datas

* @param sheet

* @throws Exception

* void

*/

private void writeSheetContent(List listColumn,List datas,HSSFSheet sheet) throws Exception {

HSSFRow row;

List listCol = getColumnList(listColumn);

for (int i = 0, index = 2; i < datas.size(); i++, index++) {

// 创建行

row = sheet.createRow(index);

for (int j = 0; j < listCol.size(); j++) {

Column c = listCol.get(j);

createCol(row, c, datas.get(i), j);

}

}

}

/**

* 创建表头

* @param listColumn 表头数组

* @return 返回表头总行数

*/

public void createHead(List listColumn, HSSFSheet sheetCo){

HSSFRow row = sheetCo.createRow(0);

HSSFRow row2 = sheetCo.createRow(1);

for(short i = 0, n = 0; i < listColumn.size(); i++){

HSSFCell cell1 = row.createCell(n);

cell1.setCellStyle(headStyle);

HSSFRichTextString text;

List columns = listColumn.get(i).getListColumn();

//双标题

if(CollectionUtils.isEmpty(columns)){

// 单标题

HSSFCell cell2 = row2.createCell(n);

cell2.setCellStyle(headStyle);

text = new HSSFRichTextString(listColumn.get(i).getContent());

sheetCo.addMergedRegion(new CellRangeAddress(0, n, 1, n));

n++;

cell1.setCellValue(text);

continue;

}

text = new HSSFRichTextString(listColumn.get(i).getContent());

cell1.setCellValue(text);

// 创建第一行大标题

sheetCo.addMergedRegion(new CellRangeAddress(0, 0, n, (short) (n + columns.size() -1)));

// 给标题赋值

for(int j = 0; j < columns.size(); j++){

HSSFCell cell2 = row2.createCell(n++);

cell2.setCellStyle(headStyle);

cell2.setCellValue(new HSSFRichTextString(columns.get(j).getContent()));

}

}

}

/**

* 创建行

* @param row

* @param column

* @param v

* @param rowIndex

* @return

* @throws Exception

*/

public int createRowVal(HSSFRow row, Column column,T v,int rowIndex) throws Exception{

// 遍历标题

if(column.getListColumn() != null && column.getListColumn().size() > 0){

for(int i = 0; i < column.getListColumn().size(); i++){

createRowVal(row,column.getListColumn().get(i),v,rowIndex);

}

}else{

createCol(row,column,v,rowIndex++);

}

return rowIndex;

}

/**

* 创建单元格

* @param row

* @param column

* @param v

* @param columnIndex

* @throws Exception

*/

public void createCol(HSSFRow row,Column column,T v,int columnIndex) throws Exception{

// 创建单元格

HSSFCell cell = row.createCell(columnIndex);

// 设置单元格样式

cell.setCellStyle(bodyStyle);

Class cls = v.getClass();

Field field = cls.getDeclaredField(column.getFieldName());

// 设置些属性是可以访问的

field.setAccessible(true);

if(field.get(v) != null){

Object value = field.get(v);

if(value instanceof Date){

value = parseDate((Date)value);

}

HSSFRichTextString richString = new HSSFRichTextString(value.toString());

cell.setCellValue(richString);

}

}

/**

* init

*/

private void init(){

// 生成表头样式

headStyle = workbook.createCellStyle();

headStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.AQUA.getIndex());

headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

headStyle.setBorderBottom(BorderStyle.THIN);

headStyle.setBorderLeft(BorderStyle.THIN);

headStyle.setBorderRight(BorderStyle.THIN);

headStyle.setBorderTop(BorderStyle.THIN);

headStyle.setAlignment(HorizontalAlignment.CENTER);

headStyle.setVerticalAlignment(VerticalAlignment.CENTER);

// 生成一个字体

HSSFFont headFont = workbook.createFont();

headFont.setColor(HSSFColor.HSSFColorPredefined.VIOLET.getIndex());

headFont.setFontHeightInPoints((short) 12);

headFont.setBold(true);

// 把字体应用到当前的样式

headStyle.setFont(headFont);

// 生成并设置另一个样式

bodyStyle = workbook.createCellStyle();

bodyStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.WHITE.getIndex());

bodyStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

bodyStyle.setBorderBottom(BorderStyle.THIN);

bodyStyle.setBorderLeft(BorderStyle.THIN);

bodyStyle.setBorderRight(BorderStyle.THIN);

bodyStyle.setBorderTop(BorderStyle.THIN);

bodyStyle.setAlignment(HorizontalAlignment.CENTER);

bodyStyle.setVerticalAlignment(VerticalAlignment.CENTER);

// 生成另一个字体

HSSFFont bodyFont = workbook.createFont();

bodyFont.setBold(false);

// 把字体应用到当前的样式

bodyStyle.setFont(bodyFont);

}

/**

* 时间转换

* @param date

* @return

* String

*/

private String parseDate(Date date){

String dateStr = "";

try{

dateStr = sdf.format(date);

} catch (Exception e){

e.printStackTrace();

}

return dateStr;

}

/**

* 拆分sheet,因为每个sheet不能超过6526,否则会报异常

* @param data

* @param listColumn

* void

*/

private void splitDataToSheets(List data,List listColumn) {

int dataCount = data.size();

int maxColumn = 65535;

int pieces = dataCount / maxColumn;

for (int i = 1; i <= pieces; i++) {

HSSFSheet sheet = workbook.createSheet(this.title + i);

List subList = data.subList((i - 1) * maxColumn, i * maxColumn);

writeSheet(sheet, subList, listColumn);

}

HSSFSheet sheet = workbook.createSheet(this.title + (pieces + 1));

writeSheet(sheet, data.subList(pieces * maxColumn, dataCount), listColumn);

}

/**

* 把column的columnList整理成一个list

* @param listColumn

* @return

* List

*/

private List getColumnList(List listColumn){

List listCol = new ArrayList<>();

for(int i = 0; i < listColumn.size(); i++){

List list = listColumn.get(i).getListColumn();

if(list.size() > 0){

for(Column c : list){

if(c.getFieldName() != null){

listCol.add(c);

}

}

}else{

if(listColumn.get(i).getFieldName() != null){

listCol.add(listColumn.get(i));

}

}

}

return listCol;

}

/**

* 保存Excel到InputStream,此方法适合web导出excel

*

* @param workbook

* @return

*/

private InputStream save(HSSFWorkbook workbook) {

ByteArrayOutputStream bos = new ByteArrayOutputStream();

try {

workbook.write(bos);

InputStream bis = new ByteArrayInputStream(bos.toByteArray());

return bis;

} catch (Exception e) {

e.printStackTrace();

throw new RuntimeException(e);

}

}

/**

* 保存文件

* @param workbook

* @param filePath

* @throws IOException

*/

private void save(HSSFWorkbook workbook,String filePath) throws IOException {

workbook.write(new FileOutputStream(filePath));

}

四、测试类

public class ExportTest {

@Data

@AllArgsConstructor

public class ValueObj {

private String value1;

private String value2;

}

public static void main(String[] args) throws Exception {

//用于存放第一行单元格

List listColumn = new ArrayList<>();

// 用于存放第一列第二行的单元格

List list2 = new ArrayList<>();

// 创建一列,value1 表示这一列需要导出字段的值

list2.add(new Column("标题1","value1"));

list2.add(new Column("标题2","value1"));

list2.add(new Column("标题3","value1"));

// 用于存放第二列第二行的单元格

List list3 = new ArrayList<>();

list3.add(new Column("标题6","value2"));

list3.add(new Column("标题7","value2"));

//创建第一行大标题,大标题的fieldName 为 null

Column c1 = new Column("标题1",null);

c1.setListColumn(list2);

Column c2 = new Column("标题2",null);

c2.setListColumn(list3);

listColumn.add(c1);

listColumn.add(c2);

//需要导出的数据

List valueList = new ArrayList<>();

valueList.add(new ValueObj("1","11"));

valueList.add(new ValueObj("2","22"));

valueList.add(new ValueObj("3","33"));

valueList.add(new ValueObj("4","44"));

ExcelHelper ta = new ExcelHelper("表格",15,20);

ta.exportExcel(listColumn, valueList,"D:\\outExcel.xls");

}

}

View Code

五、实现效果

java多表头导出excel表格_【每日一点】1. Java如何实现导出Excel单表头或多表头相关推荐

  1. matlab筛选表格数据导出,excel表格里怎么将筛选数据导出-Excel表格在进行筛选,我如何可以导出所有筛选出来......

    如何将EXCEL表格中筛选出来的数据一次性复制到另一... 使用数据透最方便下据为例: 步骤1:选择A1单元格,插入>>>数据透视表,再单击定"按钮,如下图 步骤2:勾选& ...

  2. halcon 将数据保存到excel_halcon保存数据到excel表格-怎样把图像里面的数据提取到excel表格里面去?...

    mt4如何将自定义数据保存到excel表格 这种方式嵌入的,目的就是让你没有办法简单复制粘贴.即使通过OCR之类的软件,由于存在底色.水印等,错误率也相当高,意义不是很大. 怎样把图像里面的数据提取到 ...

  3. matlab导入表格画图,matlab从excel表格导入数据画图-在matlab上如何导入excel表格然后画图...

    如何将excel表格中大量数据导入matlab中并作图 1.matlab,点击主页下面的数据导入,你可以导入excel数据,这里导自己的huitushuju文件. 2.单击"打开" ...

  4. excel表格导入matlab并画等高线,#如何将excel表格中大量数据导入matlab中并作图#excel表格里的自由画笔...

    怎样在已经制好的excel图表中插入新的数据制图 1,在excel里面你直接选中数据然击插入图表就可以啦~ 2要是想实时更新数据源可以尝试下用BDP版,只需要导入一次数据,选择并保存你想要的模板就可以 ...

  5. 在Excel表格中输入0开头的数字,调整Excel工作表显示比例。

    在Excel表格中输入0开头的数字,调整Excel工作表显示比例. 目录 在Excel表格中输入0开头的数字,调整Excel工作表显示比例. 一.在Excel表格中输入0开头的数字 1.把输入状态切换 ...

  6. 用java查询excel表格_如何把java查询出的内容导入到excel表格

    展开全部 java查询出的内容导入到excel表格 /**导出数据为XLS格式 * @param fos * @param bo */ public void writeExcelBo(FileOut ...

  7. 阿里开源(EasyExcel):使用Java将数据导出为Excel表格、带样式----》java web下载 Excel文件

    目录 一.技术选型 二.实现过程 1.导入依赖 2.编写工具类 EasyExcelUtil 3.公用参数类 EasyExcelParams 4.表格样式实体类 MyWriteHandler 5.数据实 ...

  8. easypoi导出word表格_拒绝加班,批量将word文档中的信息高效率提取出来存储到Excel中...

    最近,有小伙伴跟我提了一个需求,小伙伴是做扶贫工作的,从扶贫系统里面可以批量的导出每一户的信息到一个word文档中,导出的内容是在word中是以表格的形式存在的.小伙伴的需求是如何批量的将每个word ...

  9. access调整行高和列宽_《excel表格怎么调整行高和列宽》 EXCEL 表格如何导出至WORD 格式...

    EXCEL 表格如何导出至WORD 格式 1.演示使用的软件为word文字处理软件,软件为office家学生版2016. 2.首先打开我档,并在上方栏找到插入菜单,单击后在工具栏中找到文本-对象. 3 ...

  10. EasyExcel导出Excel表格到浏览器,并通过Postman测试导出Excel【入门案例】

    一.前言 小编最近接到一个导出Excel的需求,需求还是很简单的,只需要把表格展示的信息导出成Excel就可以了,也没有复杂的合并列什么的. 常见的导出Excel的技术: hutool easyExc ...

最新文章

  1. RTP:实时应用程序传输协议
  2. 什么是webservice?
  3. iOS 进阶 - RUNTIME 运行时
  4. oracle 计划中的view,为何执行计划中会出现个VIEW: VM_NWVW_1 ?
  5. [python opencv 计算机视觉零基础到实战] 十八、用鼠标进行画画
  6. 18-数据持久化-Data Volume
  7. java sha1withrsa公钥加密_数字签名----sha1withrsa
  8. 智能判断图片中是否存在某物体_基于WT901传感器及NB-IOT无线技术开发的一款物体倾倒监测设备...
  9. visio 输出mysql_Visio2010建立ER图并直接导出为SQL语句
  10. 一网打尽 SCI、SCIE、SSCI 、EI等指标及影响因子查询
  11. hp linux还原系统还原,酷越一键备份还原(惠普电脑系统还原)精简美化版...
  12. python 爬虫 | selenium换页问题
  13. Retina屏下的图片优化
  14. vue前端生成二维码,实现扫码下载功能
  15. C++实现石头剪刀布
  16. 【入门】大象喝水 C++题解
  17. RGB颜色值与十六进制颜色码
  18. wandb使用方法以及具体设置
  19. 郑州大学网络空间安全学院复试123
  20. 申报高新技术企业认定哪些地方需要注意?

热门文章

  1. 管道pipe-有名管道
  2. autojs读取文件夹所有文件_Auto JS 文件类操作
  3. Ubuntu下配置FreeRADIUS + PPTP/L2TP + Mysql + daloRADIUS
  4. 编译原理考试大题分析【太原理工大学】
  5. 方差分析及其在Excel、SPSS中的应用
  6. 太火爆了!这一款小游戏火到把服务器搞瘫痪,合成大西瓜
  7. 论文大致思路(不断更新)
  8. linux系统查看电脑cpu,linux系统怎么查看自己电脑的cpu位数
  9. 模版方法模式--旅游签证
  10. 一位资深开发的个人经历 【转自百度贴吧 java吧 原标题 4年java 3年产品 现在又开始做android了】...