前言

  日常开发中,Excel的导出、导入可以说是最常见的功能模块之一,一个通用的、健壮的的工具类可以节省大量开发时间,让我们把更多精力放在业务处理上中

  之前我们也写了一个Excel的简单导出,甚至可以不依赖poi,还扩展了纯前端导出Excel!详情请戳:《POI导出Excel》,遗憾的是这些导出并不支持复杂表头

  HExcel,一个简单通用的导入导出Excel工具类
    1、支持导出复杂表头(支持表头单元格水平合并、垂直合并,支持表头单元格个性化样式)
    2、支持导入读取sheet数据(只需要提供title与key的关系,不需要管列的顺序)

  代码思路都在代码注释里,感兴趣的自己看注释

  PS:依赖 poi 以及 hutool

<!-- POI -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.4</version>
</dependency>

  先睹为快

  表头目前支持以下属性,可自行扩展:

title  标题
key key
width 宽度
align 对齐方式
background-color 背景颜色(POI的IndexedColors)
color 字体颜色(POI的IndexedColors)
children 子级表头

  导出

  代码

//获取HExcel实例
HExcel hExcel1 = HExcel.newInstance(); //数据,一般是查数据库,经过数据处理生成
List<Map<String, Object>> dataList = new ArrayList<>();
HashMap<String, Object> date1 = new HashMap<>();
date1.put("user_name","张三");
date1.put("sex","男");
date1.put("age",20);
date1.put("yu_wen",90);
date1.put("ying_yu",0);
date1.put("shu_xue",85);
date1.put("wu_li",80);
date1.put("total",255);
dataList.add(date1); HashMap<String, Object> date2 = new HashMap<>();
date2.put("user_name","李四");
date2.put("sex","女");
date2.put("age",18);
date2.put("yu_wen",81);
date2.put("ying_yu",0);
date2.put("shu_xue",90);
date2.put("wu_li",70);
date2.put("total",241);
dataList.add(date2); //如果是固定表头数据,可以在项目资源文件夹下面新建个json文件夹,用来保存表头json数据,方便读、写
//JSONArray header = JSONUtil.parseArray(ResourceUtil.readUtf8Str("json/header.json")); //如果是动态表头数据,直接把json字符串写在代码里,方便动态生成表头数据 //表头
String sheetName = "学生成绩单";
JSONArray headers = JSONUtil.parseArray("" +
"[\n" +
" {\n" +
" \"title\":\""+sheetName+"\",\n" +
" \"children\":[\n" +
" {\n" +
" \"title\":\"日期:"+DateUtil.today()+"\",\n" +
" \"align\":\"right\",\n" +
" \"children\":[\n" +
" {\n" +
" \"title\":\"姓名\",\n" +
" \"key\":\"user_name\",\n" +
" },\n" +
" {\n" +
" \"title\":\"语文\",\n" +
" \"key\":\"yu_wen\",\n" +
" },\n" +
" {\n" +
" \"title\":\"数学\",\n" +
" \"key\":\"shu_xue\",\n" +
" },\n" +
" {\n" +
" \"title\":\"总分\",\n" +
" \"key\":\"total\",\n" +
" \"background-color\":17,\n" +
" \"color\":10,\n" +
" \"width\":30,\n" +
" },\n" +
" ]\n" +
" },\n" +
" ]\n" +
" },\n" +
"]" +
"");
//生成sheet
hExcel1.buildSheet(sheetName, headers, dataList); //保存成File文件
hExcel1.toFile("C:\\Users\\XFT User\\Desktop\\学生成绩单复杂表头导出测试.xls"); //关闭对象
hExcel1.close();

  效果

  导入

  需要导入的Excel文件

  代码

//需要设置title与key的关系
JSONObject headerTitleKey = new JSONObject("" +
"{\n" +
" \"姓名\":\"user_name\",\n" +
" \"语文\":\"yu_wen\",\n" +
" \"数学\":\"shu_xue\",\n" +
" \"总分\":\"total\",\n" +
"}" +
""); //根据Excel文件,获取HExcel实例
HExcel hExcel2 = HExcel.newInstance(new File("C:\\Users\\XFT User\\Desktop\\学生成绩单复杂表头导出测试.xls")); //根据title-key关系,读取指定位置的sheet数据
List<Map<String, Object>> sheetList = hExcel2.readSheet(2, 3, headerTitleKey); //打印sheetList数据
for (Map<String, Object> map : sheetList) {
System.out.println(map.toString());
} //关闭对象
hExcel2.close();

  效果

  {user_name=张三, yu_wen=90, shu_xue=85, total=255}
  {user_name=李四, yu_wen=81, shu_xue=90, total=241}

  完整代码

package cn.huanzi.qch.util;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress; import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*; /**
* HExcel,一个简单通用的导入导出Excel工具类
* 1、支持复杂表头导出(支持表头单元格水平合并、垂直合并,支持表头单元格个性化样式)
* 2、支持导入读取sheet数据(只需要提供title与key的关系,不需要管列的顺序)
*
* PS:依赖 poi 以及 hutool
*
* 详情请戳:https://www.cnblogs.com/huanzi-qch/p/17797355.html
*/
public class HExcel { /**
* 获取一个HExcel实例,并初始化空Workbook对象
*/
public static HExcel newInstance(){
HExcel hExcelUtil = new HExcel();
hExcelUtil.hSSFWorkbook = new HSSFWorkbook();
return hExcelUtil;
} /**
* 获取一个HExcel实例,并根据excelFile初始化Workbook对象
*/
public static HExcel newInstance(File excelFile){
HExcel hExcelUtil = new HExcel();
try {
hExcelUtil.hSSFWorkbook = new HSSFWorkbook(new FileInputStream(excelFile));
} catch (IOException e) {
throw new RuntimeException("【HExcel】 根据excelFile初始化Workbook对象异常",e);
}
return hExcelUtil;
} /**
* 导入并读取Excel
*
* @param sheetIndex 需要读取的sheet下标
* @param firstDataRow 数据起始行
* @param headerTitleKey title与key的关系json对象
* @return 返回数据集合
*/
public List<Map<String, Object>> readSheet(int sheetIndex,int firstDataRow,JSONObject headerTitleKey){
//最终返回的数据集合
ArrayList<Map<String, Object>> list = new ArrayList<>(); //获取sheet
HSSFSheet sheet = this.hSSFWorkbook.getSheetAt(sheetIndex); //获取title与col的对应关系
HashMap<Integer, String> headerMap = new HashMap<>();
int lastCellNum = sheet.getRow(0).getLastCellNum();
for (int i = 0; i < lastCellNum; i++) {
for (int j = firstDataRow-1; j >=0 ; j--) {
HSSFCell cell = sheet.getRow(j).getCell(i);
if(cell != null && !"".equals(cell.getStringCellValue())){
String title = cell.getStringCellValue();
headerMap.put(i,title);
break;
}
}
} //获取数据
for (int i = firstDataRow; i <= sheet.getLastRowNum(); i++) {
HSSFRow row = sheet.getRow(i);
LinkedHashMap<String, Object> dateMap = new LinkedHashMap<>();
for (int j = 0; j < lastCellNum; j++) {
String title = headerMap.get(j);
String key = headerTitleKey.getStr(title); if(key != null && !"".equals(key)){
String value = row.getCell(j).getStringCellValue();
dateMap.put(key,value);
}
}
list.add(dateMap);
} return list;
} /**
* 构造一个sheet,以及生成复杂表头、表数据
*
* @param sheetName sheet名称
* @param headers 复杂表头json数组对象
* @param dataLists 表数据集合
* @return HExcel
*/
public HExcel buildSheet(String sheetName, JSONArray headers, List<Map<String, Object>> dataLists) {
//建立新的sheet对象
HSSFSheet sheet = this.hSSFWorkbook.createSheet(sheetName);//设置表单名 //生成复杂表头
int row = 0;//当前行
int col = 0;//当前列
HashMap<String, Object> hashMap = createHeader(sheet,row,col,headers);
ArrayList<String> headerList = (ArrayList<String>) hashMap.get("keyList");
row = (int) hashMap.get("maxRow"); //取出水平合并区域数据
List<CellRangeAddress> cellRangeAddressList = sheet.getMergedRegions();
//垂直合并,单元格为空,且不属于水平合并区域
//这里row-1是因为,生成所有表头结束后,maxRow比最大行+1,
for (int i = 0; i < headerList.size(); i++) {
for (int j = 0; j <= row-1; j++) {
boolean flag = true; //单元格不为空
HSSFCell cell = sheet.getRow(j).getCell(i);
if(cell != null){
continue;
}
//检查合并区域
for (CellRangeAddress cellAddresses : cellRangeAddressList) {
int OldFirstRow = cellAddresses.getFirstRow();
int OldLastRow = cellAddresses.getLastRow();
int OldFirstCol = cellAddresses.getFirstColumn();
int OldLastCol = cellAddresses.getLastColumn(); //与合并区域重叠
if ((OldFirstRow >= j && OldLastRow <= j) && (OldFirstCol >= i && OldLastCol <= i)) {
flag = false;
break;
}
} //满足条件,将上一个单元格与最后一个单元格合并
if(flag){
mergedCell(sheet,j-1,row-1,i,i);
break;
}
}
} //开始填充数据
HSSFCellStyle dataStyle = createDataStyle(sheet);
for (Map<String, Object> map : dataLists) {
//创建内容行
HSSFRow dataHSSFRow = sheet.createRow(row);
for (int i = 0; i < headerList.size(); i++) {
String key = headerList.get(i);
Object val = map.get(key);
createCell(dataHSSFRow, i, dataStyle, val == null ? "" : String.valueOf(val));
}
row++;
} return this;
} /**
* 保存成File文件
*
* @param path 完整文件路径+文件名
*/
public void toFile(String path) {
//try-catch语法糖
try (FileOutputStream out = new FileOutputStream(path);){
this.hSSFWorkbook.write(out);
}catch (IOException e){
throw new RuntimeException("【HExcel】 Workbook对象文件流写入File异常",e);
}
} /**
* 保存到HttpServletResponse
*
* @param fileName 文件名
* @param response HttpServletResponse对象
*/
public void toHttpServletResponse(String fileName, HttpServletResponse response) {
//try-catch语法糖
try (ServletOutputStream outputStream = response.getOutputStream();){
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
response.setContentType("application/octet-stream");
this.hSSFWorkbook.write(outputStream);
}catch (Exception e){
throw new RuntimeException("【HExcel】 Workbook对象文件流写入Response异常",e);
}
} /**
* 关闭Workbook
*/
public void close(){
try{
//关闭Workbook
this.hSSFWorkbook.close();
} catch (Exception e) {
throw new RuntimeException("【HExcel】 关闭Workbook异常",e);
}
} /* 已下设置私有,对外隐藏实现细节 */ /**
* Workbook对象
*/
private HSSFWorkbook hSSFWorkbook; /**
* 构造表头
*
* @param sheet sheet
* @param row 当前操作行
* @param col 当前操作列
* @param headers 表头数据
* @return 返回一个map对象,供上级表头获取最新当前操作行、列、key集合
*/
private HashMap<String,Object> createHeader(HSSFSheet sheet, int row, int col, JSONArray headers){
//最终返回对象
HashMap<String, Object> hashMap = new HashMap<>(); //key集合
ArrayList<String> keyList = new ArrayList<>(); HSSFWorkbook wb = sheet.getWorkbook();
HSSFRow headerHSSFRow = sheet.getRow(row);
if(headerHSSFRow == null){
headerHSSFRow = sheet.createRow(row);
}
for (Object object : headers) {
JSONObject header = (JSONObject) object;
String title = (String) header.get("title");
String key = (String) header.get("key");
Object width = header.get("width");
Object align = header.get("align");
Object backgroundColor = header.get("background-color");
Object color = header.get("color");
Object children = header.get("children"); //单元格样式
HSSFCellStyle headerStyle = createHeaderStyle(sheet); //自定义单元格背景色
if(backgroundColor != null){
headerStyle.setFillForegroundColor(Short.parseShort(backgroundColor+""));
} //自定义单元格字体颜色
if(color != null){
headerStyle.getFont(wb).setColor(Short.parseShort(color+""));
} //默认单元格宽度,20
sheet.setColumnWidth(col, 20 * 256);
if(width != null){
//自定义单元格宽度
sheet.setColumnWidth(col, (int) width * 256);
} //默认水平对齐方式(水平居中)
if(align != null){
//自定义水平对齐方式
HorizontalAlignment alignment;
switch (String.valueOf(align).toUpperCase()){
case "LEFT":
alignment = HorizontalAlignment.LEFT;
break;
case "RIGHT":
alignment = HorizontalAlignment.RIGHT;
break;
default:
alignment = HorizontalAlignment.CENTER;
break;
}
headerStyle.setAlignment(alignment);
} //System.out.println(title + " " + key + " " + row + " " + col); //生成单元格同时设置内容
createCell(headerHSSFRow, col, headerStyle, title); //无子级表头
if(children == null){
//保留顺序,方便后面设置数据
keyList.add(key); //当前列+1
col++;
}
//有子级表头
else{
//递归生成子级表头前,保存父级表头col,用于水平合并
int firstCol = col; //递归调用
HashMap<String, Object> hashMap1 = createHeader(sheet, row + 1, col, (JSONArray) children); //获取最新col、key集合
col = (int) hashMap1.get("col");
hashMap.put("maxRow",hashMap1.get("maxRow"));
keyList.addAll((ArrayList<String>) hashMap1.get("keyList")); //水平合并,这里col-1是因为,生成子级表头结束后,col比最后一个下级表头+1,
if(!(firstCol == col-1)){
mergedCell(sheet,row,row,firstCol,col-1);
}
}
} //将数据设置到对象中,返回上一层
hashMap.put("maxRow",(hashMap.get("maxRow") != null ? Integer.parseInt(hashMap.get("maxRow")+"") : 0) + 1);//最大行
hashMap.put("row",row);//当前操作行
hashMap.put("col",col);//当前操作列
hashMap.put("keyList",keyList);//key集合 return hashMap;
} /**
* 创建一个单元格
*
* @param hSSFRow 当前行对象
* @param col 当前列
* @param cellStyle 单元格样式对象
* @param text 单元格内容,目前只支持字符串,如需支持更多格式可自行扩展
*/
private void createCell(HSSFRow hSSFRow, int col, HSSFCellStyle cellStyle, String text) {
HSSFCell cell = hSSFRow.createCell(col); // 创建单元格
cell.setCellStyle(cellStyle); // 设置单元格样式
cell.setCellValue(text); // 设置值
} /**
* 构造表头、数据样式
*
* @param sheet sheet
* @return 返回一个单元格样式对象
*/
private HSSFCellStyle createHeaderStyle(HSSFSheet sheet){
HSSFWorkbook wb = sheet.getWorkbook(); //表头的样式
HSSFCellStyle headerStyle = wb.createCellStyle();
headerStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
//列名的字体
HSSFFont dataFont = wb.createFont();
dataFont.setFontHeightInPoints((short) 12);
dataFont.setFontName("新宋体");
headerStyle.setFont(dataFont);// 把字体 应用到当前样式
headerStyle.setWrapText(true);//自动换行
//填充样式,前景色、天空蓝
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
headerStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex()); // 设置边框
headerStyle.setBorderBottom(BorderStyle.THIN);
headerStyle.setBorderLeft(BorderStyle.THIN);
headerStyle.setBorderRight(BorderStyle.THIN);
headerStyle.setBorderTop(BorderStyle.THIN); return headerStyle;
}
private HSSFCellStyle createDataStyle(HSSFSheet sheet){
HSSFWorkbook wb = sheet.getWorkbook(); //内容的样式
HSSFCellStyle dataStyle = wb.createCellStyle();
dataStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
//内容的字体
HSSFFont font3 = wb.createFont();
font3.setFontHeightInPoints((short) 12);
font3.setFontName("新宋体");
dataStyle.setFont(font3);// 把字体 应用到当前样式
dataStyle.setWrapText(true);//自动换行
//默认无填充
dataStyle.setFillPattern(FillPatternType.NO_FILL);
// 设置边框
dataStyle.setBorderBottom(BorderStyle.THIN);
dataStyle.setBorderLeft(BorderStyle.THIN);
dataStyle.setBorderRight(BorderStyle.THIN);
dataStyle.setBorderTop(BorderStyle.THIN); return dataStyle;
} /**
* 合并单元格
*
* @param sheet sheet
* @param firstRow 起始行
* @param lastRow 结束行
* @param firstCol 起始列
* @param lastCol 结束列
*/
private void mergedCell(HSSFSheet sheet,int firstRow, int lastRow, int firstCol, int lastCol){
//一个单元格无需合并,例如:[0,0,0,0]
if(firstRow == lastRow && firstCol == lastCol){
return;
} //先取出合并前的单元格样式
HSSFCellStyle cellStyle = sheet.getRow(firstRow).getCell(firstCol).getCellStyle(); //合并
sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol)); //解决合并后的边框等样式问题
int first;
int end;
//垂直合并
if(firstCol == lastCol){
first = firstRow;
end = lastRow+1; for (int i = first; i < end; i++) {
HSSFRow row = sheet.getRow(i);
if(row == null){
row = sheet.createRow(i);
}
HSSFCell cell = row.getCell(firstCol);
if(cell == null){
cell = row.createCell(firstCol);
}
cell.setCellStyle(cellStyle);
}
}
//水平合并
else{
first = firstCol;
end = lastCol+1; for (int i = first; i < end; i++) {
HSSFRow row = sheet.getRow(firstRow);
if(row == null){
row = sheet.createRow(firstRow);
}
HSSFCell cell = row.getCell(i);
if(cell == null){
cell = row.createCell(i);
}
cell.setCellStyle(cellStyle);
}
}
} }

  完整main测试

public static void main(String[] args) {
//获取HExcel实例
HExcel hExcel1 = HExcel.newInstance(); //数据,一般是查数据库,经过数据处理生成
List<Map<String, Object>> dataList = new ArrayList<>();
HashMap<String, Object> date1 = new HashMap<>();
date1.put("user_name","张三");
date1.put("sex","男");
date1.put("age",20);
date1.put("yu_wen",90);
date1.put("ying_yu",0);
date1.put("shu_xue",85);
date1.put("wu_li",80);
date1.put("total",255);
dataList.add(date1); HashMap<String, Object> date2 = new HashMap<>();
date2.put("user_name","李四");
date2.put("sex","女");
date2.put("age",18);
date2.put("yu_wen",81);
date2.put("ying_yu",0);
date2.put("shu_xue",90);
date2.put("wu_li",70);
date2.put("total",241);
dataList.add(date2); //如果是固定表头数据,可以在项目资源文件夹下面新建个json文件夹,用来保存表头json数据,方便读、写
//JSONArray header = JSONUtil.parseArray(ResourceUtil.readUtf8Str("json/header.json")); //如果是动态表头数据,直接把json字符串写在代码里,方便动态生成表头数据 //表头
String sheetName = "学生成绩单";
JSONArray headers = JSONUtil.parseArray("" +
"[\n" +
" {\n" +
" \"title\":\""+sheetName+"\",\n" +
" \"children\":[\n" +
" {\n" +
" \"title\":\"日期:"+DateUtil.today()+"\",\n" +
" \"align\":\"right\",\n" +
" \"children\":[\n" +
" {\n" +
" \"title\":\"姓名\",\n" +
" \"key\":\"user_name\",\n" +
" },\n" +
" {\n" +
" \"title\":\"语文\",\n" +
" \"key\":\"yu_wen\",\n" +
" },\n" +
" {\n" +
" \"title\":\"数学\",\n" +
" \"key\":\"shu_xue\",\n" +
" },\n" +
" {\n" +
" \"title\":\"总分\",\n" +
" \"key\":\"total\",\n" +
" \"background-color\":17,\n" +
" \"color\":10,\n" +
" \"width\":30,\n" +
" },\n" +
" ]\n" +
" },\n" +
" ]\n" +
" },\n" +
"]" +
"");
//生成sheet
hExcel1.buildSheet(sheetName, headers, dataList); //表头
JSONArray headers2 = JSONUtil.parseArray("" +
"[\n" +
" {\n" +
" \"title\":\"姓名\",\n" +
" \"key\":\"user_name\",\n" +
" },\n" +
" {\n" +
" \"title\":\"学科成绩\",\n" +
" \"children\":[\n" +
" {\n" +
" \"title\":\"语文\",\n" +
" \"key\":\"yu_wen\",\n" +
" },\n" +
" {\n" +
" \"title\":\"数学\",\n" +
" \"key\":\"shu_xue\",\n" +
" },\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"title\":\"总分\",\n" +
" \"key\":\"total\",\n" +
" \"align\":\"right\",\n" +
" \"background-color\":17,\n" +
" \"color\":10,\n" +
" \"width\":30\n," +
" },\n" +
"]" +
"");
//生成sheet
hExcel1.buildSheet("学生成绩单2", headers2, dataList); //表头
JSONArray headers3 = JSONUtil.parseArray("" +
"[\n" +
" {\n" +
" \"title\":\"姓名\",\n" +
" \"key\":\"user_name\"\n" +
" },\n" +
" {\n" +
" \"title\":\"性别\",\n" +
" \"key\":\"sex\"\n" +
" },\n" +
" {\n" +
" \"title\":\"年龄\",\n" +
" \"key\":\"age\"\n" +
" },\n" +
" {\n" +
" \"title\":\"学科成绩\",\n" +
" \"children\":[\n" +
" {\n" +
" \"title\":\"语言类\",\n" +
" \"children\":[\n" +
" {\n" +
" \"title\":\"语文\",\n" +
" \"key\":\"yu_wen\",\n" +
" \"background-color\":7,\n" +
" \"color\":5,\n" +
" },\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"title\":\"科学类\",\n" +
" \"background-color\":10,\n" +
" \"children\":[\n" +
" {\n" +
" \"title\":\"数学\",\n" +
" \"key\":\"shu_xue\"\n" +
" },\n" +
" {\n" +
" \"title\":\"物理\",\n" +
" \"key\":\"wu_li\"\n" +
" }\n" +
" ]\n" +
" },\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"title\":\"总分\",\n" +
" \"key\":\"total\",\n" +
" \"align\":\"right\",\n" +
" \"background-color\":17,\n" +
" \"color\":10,\n" +
" \"width\":30\n," +
" },\n" +
"]"+
"");
//生成sheet
hExcel1.buildSheet("学生成绩单3", headers3, dataList); //表头
JSONArray headers4 = JSONUtil.parseArray("" +
"[\n" +
" {\n" +
" \"title\":\"姓名\",\n" +
" \"key\":\"user_name\"\n" +
" },\n" +
" {\n" +
" \"title\":\"性别\",\n" +
" \"key\":\"sex\"\n" +
" },\n" +
" {\n" +
" \"title\":\"年龄\",\n" +
" \"key\":\"age\"\n" +
" },\n" +
" {\n" +
" \"title\":\"学科成绩\",\n" +
" \"children\":[\n" +
" {\n" +
" \"title\":\"语文\",\n" +
" \"key\":\"yu_wen\",\n" +
" },\n" +
" {\n" +
" \"title\":\"科学类\",\n" +
" \"background-color\":10,\n" +
" \"children\":[\n" +
" {\n" +
" \"title\":\"数学\",\n" +
" \"key\":\"shu_xue\"\n" +
" },\n" +
" {\n" +
" \"title\":\"物理\",\n" +
" \"key\":\"wu_li\"\n" +
" }\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"title\":\"英语\",\n" +
" \"key\":\"ying_yu\",\n" +
" },\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"title\":\"总分\",\n" +
" \"key\":\"total\",\n" +
" \"align\":\"right\",\n" +
" \"background-color\":17,\n" +
" \"color\":10,\n" +
" \"width\":30\n" +
" \n" +
" }\n" +
"]"+
"");
//生成sheet
hExcel1.buildSheet("学生成绩单4", headers4, dataList); //保存成File文件
hExcel1.toFile("C:\\Users\\XFT User\\Desktop\\学生成绩单复杂表头导出测试.xls");
System.out.println("导出完成!\n"); //关闭对象
hExcel1.close(); //导入 //需要设置title与key的关系
JSONObject headerTitleKey = new JSONObject("" +
"{\n" +
" \"姓名\":\"user_name\",\n" +
" \"语文\":\"yu_wen\",\n" +
" \"数学\":\"shu_xue\",\n" +
" \"总分\":\"total\",\n" +
"}" +
""); //根据Excel文件,获取HExcel实例
HExcel hExcel2 = HExcel.newInstance(new File("C:\\Users\\XFT User\\Desktop\\学生成绩单复杂表头导出测试.xls")); //根据title-key关系,读取指定位置的sheet数据
List<Map<String, Object>> sheetList = hExcel2.readSheet(2, 3, headerTitleKey); //打印sheetList数据
System.out.println("导入完成!");
for (Map<String, Object> map : sheetList) {
System.out.println(map.toString());
} //关闭对象
hExcel2.close(); }

  后记

  一个简单通用的导入导出Excel工具类暂时先记录到这,后续再进行补充

HExcel,一个简单通用的导入导出Excel工具类的更多相关文章

  1. 导入导出Excel工具类ExcelUtil

    前言 前段时间做的分布式集成平台项目中,许多模块都用到了导入导出Excel的功能,于是决定封装一个ExcelUtil类,专门用来处理Excel的导入和导出 本项目的持久化层用的是JPA(底层用hibe ...

  2. NPOI导入导出Excel工具类

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Ref ...

  3. javaEE开发之导出excel工具类

    web开发中,一个系统的普通需求也包含导出excel,一般採用POI做统计报表导出excel. 导出excel工具类: import java.io.FileOutputStream; import ...

  4. Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类

    Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类 ============================== ©Copyright 蕃薯耀 20 ...

  5. 关于Excel导入导出POI工具类

    import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import ...

  6. Java XSSF 导出excel 工具类

    参数解释: title:导出excel标题.headers 导出到excel显示的列头. columns 对应数据库字段 .list 导出数据1.pox中添加依赖 <dependency> ...

  7. 使用POI导出EXCEL工具类并解决导出数据量大的问题

    POI导出工具类 工作中常常会遇到一些图表需要导出的功能,在这里自己写了一个工具类方便以后使用(使用POI实现). 项目依赖 <dependency> <groupId>org ...

  8. java导出excel工具类

    java导出excel须要使用HSSFWorkbook这个类,须要导入poi-3.6-20091214.jar 工具类调用例如以下: package com.qlwb.business.util; i ...

  9. 导出Excel工具类

    import java.io.OutputStream; import java.lang.reflect.Method; import java.text.SimpleDateFormat; imp ...

  10. JXL导出Excel工具类

    将Excel中的数据读取到List<Map<String, Object>>集合中   package com.mvc.util;   import java.io.File; ...

随机推荐

  1. 2023-07-11:给定正整数 n, 返回在 [1, n] 范围内具有 至少 1 位 重复数字的正整数的个数。 输入:n = 100。 输出:10。

    2023-07-11:给定正整数 n, 返回在 [1, n] 范围内具有 至少 1 位 重复数字的正整数的个数. 输入:n = 100. 输出:10. 答案2023-07-11: 函数的主要思路如下: ...

  2. 盘古大模型加持,华为云开天aPaaS加速使能千行百业应用创新

    摘要:开天aPaaS,让优秀快速复制,支撑开发者及伙伴上好云.用好云. 本文分享自华为云社区<盘古大模型加持,华为云开天aPaaS加速使能千行百业应用创新>,作者:开天aPaaS小助手. ...

  3. Maven配置UTF8,JDK版本

    <!-- 局部jdk配置,pom.xml中 --> <build> <plugins> <plugin> <groupId>org.apac ...

  4. 智能制造之路—从0开始打造一套轻量级MOM平台

    一.概述 面对数字化浪潮,MOM需求迈入上升期,数字化从"可选项"变成了企业竞争"必选项".制造行业每个工厂的生产逻辑都不尽相同,流程的梳理.数据统一化都需要调 ...

  5. 洛谷 T356695 文字处理软件(重置版)

    很简单了啊! 说普及- 我都不信 作者(也就是我)链接:https://www.luogu.com.cn/problem/T356695 好好想想!!!! 题目! 文字处理软件(重置版) 题目背景 A ...

  6. Verilog实现奇分频电路

    在FPGA中,计数器电路用途很广,一般计数器电路都可作为分频电路.实现占空比为50的偶分频电路很好实现.但实现占空比为50的奇分频电路有点难度.下面给出一个简单例子,记录学习奇分频电路的过程. 实现占 ...

  7. 修改启动配置文件更改root密码

    第二种:修改启动配置文件 (1)进入救援模式 开机选择第一个系统内核,键入e (2)修改配置文件 将光标移动linux 开始的行,添加内核参数 rd.break 按ctrl-x启动 光标放在linux ...

  8. quarkus依赖注入之七:生命周期回调

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇的知识点是bean的生命周期回调:在be ...

  9. webpack是如何处理css/less资源的呢

    上一篇文章 体验了webpack的打包过程,其中js文件不需要我们手动配置就可以成功解析,可其它类型的文件,比如css.less呢? css-loader 首先,创建一个空文件夹,通过 npm ini ...

  10. 图加速数据湖分析-GeaFlow和Apache Hudi集成

    表模型现状与问题 关系模型自1970年由埃德加·科德提出来以后被广泛应用于数据库和数仓等数据处理系统的数据建模.关系模型以表作为基本的数据结构来定义数据模型,表为二维数据结构,本身缺乏关系的表达能力, ...