Java-Maven-POI 简单导入导出Excel通用工具,默认使用基于poi实现
2018-02-01 14:40
1126 查看
个人项目
GitHub地址:https://github.com/83945105/holygrail
Maven坐标: 目前最新版0.0.4
欢迎到官网搜索最新版:
地址一:点击打开链接
地址二:点击打开链接
导入导出目前实现了常用功能,后续我会不断完善,如添加字体设置
2、连续创建Sheet表
3、自定义标题(这种方式可以动态创建列)
4、用js文件描述标题(这种方式正常操作不能动态创建列,你要是动态生成这个文件当我没说)
基于模板我把表头文件修改成这种,如果你会使用easyui的datagrid的columns属性,
那你就很好理解为什么标题要用二维数组来描述
5、复杂的标题(合并单元格,以js文件方式为例)
修改标题js如上,二维数组第一维表示一行,rowSpan表示占用行数,colSpan表示占用列数
导出Excel效果如下
6、格式化单元格
除了标题单元格可以自定义,数据单元格同样可以自定义(格式化)
我们将上面的标题js加入一个序号列,占用2行
再来一个更复杂点的例子
这里我将"占用2行"这列writeEmpty设为false,因为我接下来会格式化手机号列对应的数据单元格,来占用这个列,如果不将writeEmpty设为false,如果单元格值类型对应不上,将报异常,或者打开Excel会提示存在单元格值被覆盖之类的提示。
7、最后再丢几个批量创建Sheet的例子
此外还有一些方法,我就不贴代码了,如设置行号,设置列号控制导入数据的起始行之类的,方法都有详细的注释,用IDE提示就能看到所有方法,基本什么功能都能猜到。
所有例子读取以上模板
1、同样先来几个简单的例子
这种方式我会将每行数据塞入一个ArrayList,单元格值按照列顺序排列
2、指定列值获取数据
指定了列值后,默认会将数据注入HashMap,列值为Key,单元格值为Value,如果此时存在没指定列值的单元格,将会使用坐标作为Key,如A1表示第一行第一列,B4表示第四行第二列。
细心会发现,username对应了序号,这是因为设置列值必须自己控制顺序,默认从第一列开始
3、使用标题二维数组或者js文件读取Excel(详情见导出)
4、自定义全局接收数据对象
5、自定义行接收对象
6、连续读取存在的Sheet
GitHub地址:https://github.com/83945105/holygrail
Maven坐标: 目前最新版0.0.4
<groupId>com.github.83945105</groupId> <artifactId>holygrail</artifactId>
欢迎到官网搜索最新版:
地址一:点击打开链接
地址二:点击打开链接
导入导出目前实现了常用功能,后续我会不断完善,如添加字体设置
开始教程
一、导出
1、废话不多说,先来2个最简单的例子/*模拟从数据库获取数据开始*/ Collection<Map<String, Object>> records = new ArrayList<>(); Map<String, Object> record01 = new HashMap<>(); Map<String, Object> record02 = new HashMap<>(); Map<String, Object> record03 = new HashMap<>(); record01.put("username", "张三1"); record01.put("password", "666"); record02.put("username", "张三2"); record02.put("password", "666"); record03.put("username", "张三3"); record03.put("password", "666"); records.add(record01); records.add(record02); records.add(record03); /*模拟从数据库获取数据结束*/ Export.buildSXSSFExportExcelWorkBook()//构建查询对象 .createSheet()//创建一个Sheet,可以传参设置Sheet名 .setColumnFields("username","password")//设置列字段,对应Map集合的key .importData(records)//导入数据,支持多次导入 .export("E://测试.xlsx");//导出成Excel
/*模拟从数据库获取数据开始*/ Collection<User> records = new ArrayList<>(); User user01 = new User(); User user02 = new User(); User user03 = new User(); user01.setUsername("张三1"); user01.setPassword("666"); user02.setUsername("张三2"); user02.setPassword("666"); user03.setUsername("张三3"); user03.setPassword("666"); records.add(user01); records.add(user02); records.add(user03); /*模拟从数据库获取数据结束*/ Export.buildSXSSFExportExcelWorkBook()//构建查询对象 .createSheet()//创建一个Sheet,可以传参设置Sheet名 .setColumnFields("username","password")//设置列字段,对应User对象的属性名 .importData(records)//导入数据,支持多次导入 .export("E://测试.xlsx");//导出成Excel
2、连续创建Sheet表
/*模拟从数据库获取数据开始*/ Collection<User> records = new ArrayList<>(); User user01 = new User(); User user02 = new User(); User user03 = new User(); user01.setUsername("张三1"); user01.setPassword("666"); user01.setMobile("110"); user02.setUsername("张三2"); user02.setPassword("666"); user01.setMobile("120"); user03.setUsername("张三3"); user03.setPassword("666"); user01.setMobile("119"); records.add(user01); records.add(user02); records.add(user03); /*模拟从数据库获取数据结束*/ Export.buildSXSSFExportExcelWorkBook() .createSheet() .setColumnFields("username","password") .importData(records) .getOwnerWorkBook() .createSheet("SheetB")//创建第二个Sheet,设置了Sheet名 .setColumnFields("mobile") .importData(records) .export("E://测试.xlsx");
3、自定义标题(这种方式可以动态创建列)
//构建用于描述标题的二维数组,获取数据代码略 SXSSFExcelTitle[][] titles = new SXSSFExcelTitle[1][]; SXSSFExcelTitle[] title = new SXSSFExcelTitle[3]; title[0] = new SXSSFExcelTitle(); title[1] = new SXSSFExcelTitle(); title[2] = new SXSSFExcelTitle(); title[0].setField("username");//设置标题所在列对应数据的字段 title[1].setField("password"); title[2].setField("mobile"); title[0].setTitle("姓名");//设置标题名称 title[1].setTitle("密码"); title[2].setTitle("手机号"); title[0].setWidth(50);//设置列宽,默认10,由于计算原因,实际效果稍有误差 title[1].setWidth(60); title[2].setWidth(70); title[0].setHAlign(CellStyle.H_AlignType.LEFT);//设置水平对齐方式为左对齐,标题默认水平居中 title[0].setVAlign(CellStyle.V_AlignType.BOTTOM);//设置垂直对齐方式为底部对齐,标题默认垂直居中 title[0].setBorderLeft(CellStyle.BorderStyle.DASH_DOT);//设置左边框样式,同样还可以设置其它方向边框 titles[0] = title; Export.buildSXSSFExportExcelWorkBook() .createSheet() .setTitles(titles)//设置标题 .importData(records) .export("E://测试.xlsx");
4、用js文件描述标题(这种方式正常操作不能动态创建列,你要是动态生成这个文件当我没说)
ExcelWorkBookExport.exportTemplateJavaScriptFile("E://user.js");//你可以这样导出一个模板文件
[[{ title: '姓名', field: 'username', width: 20, borderLeft: 'DASHED' },{ title: '密码', field: 'password', hAlign: 'Left', vAlign: 'top', width: 30 },{ title: '手机号', field: 'mobile', width: 15 }]]
基于模板我把表头文件修改成这种,如果你会使用easyui的datagrid的columns属性,
那你就很好理解为什么标题要用二维数组来描述
Export.buildSXSSFExportExcelWorkBook() .createSheet() //解析一个标题文件,文件放在你能加载到的位置就可以,这里我使用输入流的方式 .parseTitlesJson(Test.class.getResourceAsStream("/com/xx/xx/xx/xx/user.js")) .importData(records) .export("E://测试.xlsx");
5、复杂的标题(合并单元格,以js文件方式为例)
[[{ title: '姓' }, { title: '名' }, { title: '密码+手机号', colSpan: 2 }, { title: '占用2行', rowSpan: 2 }], [ { title: '姓名', field: 'username', width: 20, colSpan: 2 }, { title: '密码', field: 'password', width: 15 }, { title: '手机号', field: 'mobile', width: 15 } ]]
修改标题js如上,二维数组第一维表示一行,rowSpan表示占用行数,colSpan表示占用列数
导出Excel效果如下
6、格式化单元格
除了标题单元格可以自定义,数据单元格同样可以自定义(格式化)
我们将上面的标题js加入一个序号列,占用2行
Export.buildSXSSFExportExcelWorkBook()//构建查询对象 .createSheet()//创建一个Sheet,可以传参设置Sheet名 .parseTitlesJson(Test.class.getResourceAsStream("/com/xx/xx/xx/xx/user.js")) //使用lambda表达式作为第二个参数格式化单元格,如果你会写JavaScript可以理解为JS的回调函数 .importData(records, (value, record, cellHandler, field, rowCursor, index) -> { //value => 当前单元格的值 //record => 当前行数据 //cellHandler => 用于设置和获取单元格属性样式的对象,这个对象可以自己点进去看注释,可以干很多事情 //field => 当前单元格对应的title field //rowCursor => 行游标,记录当前写入行的游标号,该号从0开始 //index => 当前行数据也就是record在数据集合records中的下标 if("num".equals(field)) {//如果是序号列 cellHandler.setHAlign("center");//设置单元格为水平居中,支持直接传入字符串 cellHandler.setVAlign(CellStyle.V_AlignType.CENTER);//设置单元格为垂直居中 cellHandler.setType(CellOption.CellType.COMBOBOX);//设置单元格类型为下拉框 cellHandler.setOptions(new String[]{"下拉框值1", "下拉框值2"});//设置下拉框值 return index + 1;//使用下标号+1作为单元格值 } return value; })//导入数据,支持多次导入 .export("E://测试.xlsx");
再来一个更复杂点的例子
[[{ title: '序号', field: 'num', rowSpan: '2' }, { title: '姓' }, { title: '名' }, { title: '密码+手机号', colSpan: 2 }, { title: '占用2行', rowSpan: 2, writeEmpty: false }], [ { title: '姓名', field: 'username', width: 20, colSpan: 2 }, { title: '密码', field: 'password', width: 15 }, { title: '手机号', field: 'mobile', width: 15 } ]]主要说下writeEmpty属性,这个属性默认是true,表示当该列的单元格值为空的时候,也写入数据,
这里我将"占用2行"这列writeEmpty设为false,因为我接下来会格式化手机号列对应的数据单元格,来占用这个列,如果不将writeEmpty设为false,如果单元格值类型对应不上,将报异常,或者打开Excel会提示存在单元格值被覆盖之类的提示。
Export.buildSXSSFExportExcelWorkBook() .createSheet() .parseTitlesJson(Test.class.getResourceAsStream("/com/xx/xx/xx/xx/user.js")) .importData(records, (value, record, cellHandler, field, rowCursor, index) -> { //设置所有数据单元格为水平垂直居中 cellHandler.setHAlign("center"); cellHandler.setVAlign("center"); if("num".equals(field)) { //如果是序号列,将值改为当前数据下标+1 return index + 1; } if("username".equals(field)) { //如果是用户名列,将单元格改为占用3列 cellHandler.setColSpan(3); } if("password".equals(field)) { //如果是密码列,将单元格起始行下移一行 cellHandler.setStartRowNum(cellHandler.getStartRowNum() + 1); //占用行改为3行 cellHandler.setRowSpan(3); } if("mobile".equals(field)) {//如果是手机号列 //手机号列占用行改为5行 cellHandler.setRowSpan(5); //占用列改为2行 cellHandler.setColSpan(2); //将值格式化成数值类型 return Integer.parseInt(value == null ? "" : value.toString()); } return value; })//导入数据,支持多次导入 .export("E://测试.xlsx");//导出成Excel
7、最后再丢几个批量创建Sheet的例子
Export.buildSXSSFExportExcelWorkBook() //批量创建10个sheet .createSheets(10, (sheet, sheetIndex, index, totalAllSheetDataSize, totalSheetDataSize) -> { //sheet => 当前创建的sheet对象 //sheetIndex => 当前创建的sheet在整个工作簿中的下标 //index => 当前创建的sheet在这个批次sheet的下标 //totalAllSheetDataSize => 整个工作簿已经导入的数据总数 //totalSheetDataSize => 这个批次sheet已经导入的数据总数 sheet.setColumnFields("") .importData(new ArrayList<>()); }).export("E://批量Sheet.xlsx");
Export.buildSXSSFExportExcelWorkBook() //批量创建10个sheet .createSheets(10, (sheetIndex, index) -> "格式化Sheet名", (sheet, sheetIndex, index, totalAllSheetDataSize, totalSheetDataSize) -> { sheet.setColumnFields("") .importData(new ArrayList<>()); }).export("E://批量Sheet.xlsx");
Export.buildSXSSFExportExcelWorkBook() .createSheets((sheet, sheetIndex, index, totalAllSheetDataSize, totalSheetDataSize) -> { sheet.parseTitlesJson("") .importData(new HashSet<>()); if(totalSheetDataSize > 1000) { //当导入的数据大于1000条,停止创建Sheet return false; } return true;//继续创建Sheet,内部限制最大100个 }).export("E://批量Sheet.xlsx");
此外还有一些方法,我就不贴代码了,如设置行号,设置列号控制导入数据的起始行之类的,方法都有详细的注释,用IDE提示就能看到所有方法,基本什么功能都能猜到。
二、导入
所有例子读取以上模板
1、同样先来几个简单的例子
ArrayList<ArrayList<String>> records = Import.buildXSSFImportExcelWorkBook() .parseFile(new File("E://测试.xlsx"))//解析一个Excel .getSheet(0)//获取下标为0的Sheet .readRows()//读取数据 .getReadData();//获得读取的数据集合
这种方式我会将每行数据塞入一个ArrayList,单元格值按照列顺序排列
Import.buildXSSFImportExcelWorkBook() .parseFile(new File("E://测试.xlsx"))//解析一个Excel .getSheet(0)//获取下标为0的Sheet .readRows((record, records, rowNum, index) -> { ArrayList<?> _record = (ArrayList<?>) record;//一行行获取数据 System.out.println(_record.get(0));//取每条数据的第一列的值 });在lambda函数中获取当前读取行的数据
2、指定列值获取数据
ArrayList<HashMap<String, Object>> records = Import.buildXSSFImportExcelWorkBook() .parseFile(new File("E://测试.xlsx")) .getSheet(0) .setColumnFields("username", "password")//设置列值 .readRows() .getReadData();
指定了列值后,默认会将数据注入HashMap,列值为Key,单元格值为Value,如果此时存在没指定列值的单元格,将会使用坐标作为Key,如A1表示第一行第一列,B4表示第四行第二列。
细心会发现,username对应了序号,这是因为设置列值必须自己控制顺序,默认从第一列开始
Import.buildXSSFImportExcelWorkBook() .parseFile(new File("E://测试.xlsx")) .getSheet(0) .setColumnFields(2,"num", "username", "password")//设置列值,2表示标题占用2行,那么接下来读取数据将从第三行开始 .readRows((record, records, rowNum, index) -> { HashMap<String, Object> _record = (HashMap<String, Object>) record; System.out.println(_record.get("")); });同样可以一行行获取数据
3、使用标题二维数组或者js文件读取Excel(详情见导出)
Import.buildXSSFImportExcelWorkBook() .parseFile(new File("E://测试.xlsx")) .getSheet(0) .parseTitlesJson(Test2.class.getResourceAsStream("/com/xx/xx/xx/xx/user.js")) .readRows((record, records, rowNum, index) -> { HashMap<String, Object> _record = (HashMap<String, Object>) record; System.out.println(_record.get("")); });二维数组方式同导出,这里就不写了
4、自定义全局接收数据对象
Import.buildXSSFImportExcelWorkBook() .parseFile(new File("E://测试.xlsx")) .getSheet(0) //解析标题文件,并指定使用LinkedHashMap作为数据容器接收数据 .parseTitlesJson(Test2.class.getResourceAsStream("/com/xx/xx/xx/xx/user.js"), LinkedHashMap.class) .readRows((record, records, rowNum, index) -> { LinkedHashMap<String, Object> _record = (LinkedHashMap<String, Object>) record; System.out.println(_record.get("")); });
Import.buildXSSFImportExcelWorkBook() .parseFile(new File("E://测试.xlsx")) .getSheet(0) //解析标题文件,并指定使用User对象作为数据容器接收数据 .parseTitlesJson(Test2.class.getResourceAsStream("/com/xx/xx/xx/xx/user.js"), User.class) .readRows((record, records, rowNum, index) -> { //这里可以转成User对象获取数据 User _record = (User) record; System.out.println(_record.getUsername()); });
5、自定义行接收对象
Import.buildXSSFImportExcelWorkBook() .parseFile(new File("E://测试.xlsx")) .getSheet(0) .parseTitlesJson(Test2.class.getResourceAsStream("/com/xx/xx/xx/xx/user.js"), HashMap.class) .readRows(User.class, (record, records, rowNum, index) -> { //读取行时指定对象,覆盖全局,此时不用强转,可直接推导出类型 System.out.println(record.getUsername()); });
6、连续读取存在的Sheet
Import.buildXSSFImportExcelWorkBook() .parseFile(new File("E://测试.xlsx")) .readSheets((sheet, index) -> { //读取当前Sheet数据 sheet.setColumnFields("") .readRows(User.class, (record, records, rowNum, index1) -> { System.out.println(record.getUsername()); }); });
Import.buildXSSFImportExcelWorkBook() .parseFile(new File("E://测试.xlsx")) .readSheets((sheet, index) -> { //读取当前Sheet数据 sheet.setColumnFields("") .readRows(User.class, (record, records, rowNum, index1) -> { System.out.println(record.getUsername()); }); if(sheet.getAllReadData().size() > 1000) { //当读取的数据总数大于1000,停止读取下一个Sheet return false; } return true; });读取比较简单,就不详细说了。
相关文章推荐
- 【JavaWeb开发】使用java实现简单的Excel文件的导入与导出(POI)
- 一个基于POI的通用excel导入导出工具类的简单实现及使用方法
- java Excel导入导出,基于XML的实现,easy-excel使用
- java Excel导入导出,基于XML的实现,easy-excel使用
- 基于POI的Excel导入导出(JAVA实现)
- 使用POI实现在java程序中导入导出Excel文件数据
- java Excel导入导出,基于XML的实现,easy-excel使用
- JAVA实现数据库数据导入/导出到Excel(POI)
- java实现excel的导入导出(poi详解)
- java实现excel的导入导出(poi详解)[转]
- java中使用poi实现导入Excel
- Java使用POI实现数据导出excel报表
- java实现excel的导入导出(poi详解)
- java使用poi实现大数据量导出为EXCEL
- Java使用POI实现数据导出excel报表
- java中使用poi实现导入Excel
- java实现excel的导入导出(poi详解)
- Java使用POI实现数据导出excel报表
- 使用POI 实现 Excel 导入导出
- java实现excel的导入导出(poi详解)