Excel 导入导出
公共方法包结构
公共导入导出后端依赖pangea-common/pangea-common-excel
或pangea-common/pangea-common-excel3
包
老版本:
xml
<dependency>
<groupId>com.hisense.pangea</groupId>
<artifactId>pangea-common-excel</artifactId>
</dependency>
新版本:
xml
<dependency>
<groupId>com.hisense.pangea</groupId>
<artifactId>pangea-common-excel3</artifactId>
</dependency>
适用范围
Pangea v2.8.3+
使用方法
1.模板上传
模板上传为公共接口,无需后端开发代码
- 请求路径 域名+模块名+/common/excels/uploadTemplate
例如在pangea-system模块中,请求路径为:域名+/system/common/excels/uploadTemplate
- 请求方式
POST multipart/form-data
- 传入参数
{
"file":模板文件,
"fileName":"模板文件名称"
}
返回样例
{
"msg": "success",
"code": 0
}
2.模板下载
模板下载为公共接口,无需后端开代码
- 请求路径
网关域名
+模块名
+/common/excels/downloadTemplate
例如在
pangea-system
模块中,请求路径为:域名
+/system/common/excels/downloadTemplate
请求方式
GET传入参数
请求路径?fileName=测试
- 返回参数
文件返回以文件流方式返回,无需另外处理
3.数据导入
数据导入分两个请求,第一个请求为数据文件解析,第二个为批量保存请求, 用户上传文件后将发送第一个请求,解析后的数据返回到前端预览,预览确认没问题后,将请求第二个批量保存请求。
第一个解析请求由框架提供,无需编写代码;第二个请求由业务系统开发人员编写。
以下为解析请求:
请求路径
网关域名
+模块名
+/common/excels/upload
请求方式
POST multipart/form-data
- 传入参数
{
"file":数据文件.xlsx
}
- 返回样例
{
"msg": "success",
"code": 200,
"data": [
{
"filename": "Pangea2.0LDAP账号导入模板.xlsx",
"data": [
{
"A": "zhaoqi.ex"
}
],
"header": {
"A": "LDAP账号"
},
"sheet": "Sheet1"
}
]
}
数据导入后会在前端展示出数据,想把数据保存到数据库还需要一个自定义的保存方法,默认调用的是/api/system/**/saveBatch
需要在controller里加上该方法
java
/**
* 批量修改
*/
@PostMapping("saveBatch")
public boolean saveBatch(@RequestBody List<xxx> xxxList) {
return xxxService.saveBatch(xxxList);
}
4.数据导出
数据导出请求由业务开发人员编写,请求处理逻辑分为两步,第一步查询要导出的数据,第二步生成excel
文件并返回前端。 由于业务关联性较强,具体导出的数据在业务没确定之前框架是不知道的,所以框架只提供第二步的公共方法,即生成excel
文件并返回前端。
数据查询后请调用以下方法生成excel
文件:
/**
* 导出数据
*
* @param fileName 自定义文件名 可为空
* @param title 表头 可为空
* @param headers 列名集合(excel列头)
* @param fields 字段集合
* @param dataList 数据集合
* @param response 请求响应
*/
public static void exportByResponse(String fileName, String title, List<String> headers, List<String> fields, List dataList, HttpServletResponse response)
调用DEMO:
/**
* @date 2020-04-13
* @desc导出数据(Get请求)
* @param response languageId, languageKey(like), defaultName(like)
*/
@GetMapping("/export")
public void exportData(HttpServletResponse response, @RequestBody Map<String, List<String>> params, Long languageId, String languageKey, String defaultName) {
List<String> headers = params.get("headers");//headers对应表头名称
List<String> columns = params.get("columns");//columns对应字段名称,columns与headers一一对应
List<LangValue> userList = langValueService.findLanguageByIdAndKey(languageId,languageKey,defaultName);//userList为需要导出的数据
ExcelService.exportByResponse(null,null, headers, columns, userList, response);
}
/**
* @date 2020-04-13
* @desc导出数据(Post请求)
* @param response languageId, languageKey(like), defaultName(like)
*/
@PostMapping("/export")
public void exportData(HttpServletResponse response, @RequestBody Map<String, List<String>> params, Long languageId, String languageKey, String defaultName) {
List<String> headers = params.get("headers");//headers对应表头名称
List<String> columns = params.get("columns");//columns对应字段名称,columns与headers一一对应
List<LangValue> userList = langValueService.findLanguageByIdAndKey(languageId,languageKey,defaultName);//userList为需要导出的数据
ExcelService.exportByResponse(null,null, headers, columns, userList, response);
}
自定义表头宽度导出excel调用DEMO:
@PostMapping("/exportWidth")
public void exportDataWidth(HttpServletResponse response, @RequestBody Map<String, List<String>> params, Long languageId, String languageKey, String defaultName, String width) throws Exception {
List<String> requestHeaders = params.get("headers");
List<String> excelHeaders = new ArrayList<>();
List<String> excelColumns = new ArrayList<>();
// 根据systemName查询语言id
String[] languageIdList = languageService.selectLanguageIdBySystemName(new Language());
// 设置导出excel表头
excelHeaders.add(0, requestHeaders.get(0));
excelColumns.add(0, "LANGUAGE_KEY");
for (int i = 0; i < languageIdList.length; i++) {
Language language = languageService.selectLanguageById(Integer.parseInt(languageIdList[i]));
excelHeaders.add(i + 1, language.getLanguageName());
excelColumns.add(i + 1, language.getLanguageName());
}
Map<String, Object> requestParam = new HashMap<>();
if (languageIdList != null) {
requestParam.put("languageIdTemp", languageIdList);
}
//得到key最多的ID
String languageid = languageService.selectLanguageMaxKey(requestParam);
// 导出数据
List<Map<String, Object>> dataList = langValueService.selectExportData(Long.parseLong(languageid), defaultName, languageIdList);
String fileName = "Excel-" + String.valueOf(System.currentTimeMillis()).substring(4, 13) + ".xls";
fileName = URLEncoder.encode(fileName, "utf-8");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=" + new String((fileName + ".xlsx").getBytes("GBK"), "ISO-8859-1"));
String encrypt = ServletUtils.getRequest().getParameter("encrypt");
if (encrypt != null && encrypt.equals("true")) {
ExcelService.export(null, excelHeaders, excelColumns, dataList, response.getOutputStream(), true, Integer.parseInt(width));
} else {
ExcelService.export(null, excelHeaders, excelColumns, dataList, response.getOutputStream(), false, Integer.parseInt(width));
}
}
5.读取多个sheet页数据
- 老版本
读取excel中有多少个sheet页,调用方法如下:
java
com.hisense.pangea.service.ExcelService
public static List<Sheet> readAllSheets(InputStream is) throws Exception;
public static List<Sheet> readAllSheets(InputStream is, boolean includeHidden) throws Exception;
读取指定sheet页中的数据,调用方法如下:
java
com.hisense.pangea.service.ExcelService
/**
* 普通列表数据导入
*
* @param configMap {
* sheet:String/Integer sheet页名称或索引(从0开始) 必须
* beanClass:Class 导入后封装的对象(此对象必须可实例化且包含空构造,常见取值:JavaBean,Map,JSONObject等) 必须
* fields:List<String> 数据列对应的对象字段名称 必须
* startRow:Integer 列表数据开始行索引(从0开始) 必须
* startCol:Integer 列表数据开始列索引(从0开始) 必须
* prepareListener:Map<String, Class<? extends IReaderPrepareListener>> 数据读取前置监听器 非必须
* afterListener:Map<String, Class<? extends IReaderAfterListener>> 数据读取后置监听器 非必须
* exceptionListener:IReaderExceptionListener 数据转换和对象赋值异常监听器 非必须
* typeMapping:Map<String,Class> 数据类型指定,如果封装为JavaBean则建议不设置 非必须
* skipErrors:Boolean 是否忽略错误 默认false 非必须
* }
*/
public static <T> List<T> readLoop(Map<String, Object> configMap, InputStream is) throws Exception;
- 新版本
读取excel中有多少个sheet页,调用方法如下:
java
com.hisense.pangea.excel3.read.ExcelSheetReader
List<Sheet> getAllSheets(Workbook workbook);
List<Sheet> getAllSheets(String filepath);
List<Sheet> getAllSheets(InputStream is);
读取指定sheet页中的数据,调用方法如下:
java
com.hisense.pangea.service.ExcelService
List<T> read(InputStream is, int sheetIndex, int headRows);
测试方法
如需要本地调试,请使用PostMan工具
本地PostMan
调试示例:
模板上传:
模板下载:
框架使用导入导出功能
基于以上的导入导出,框架为了方便各业务项目切换自己的环境,提供了基础数据的导出和导入功能(基础服务->公共数据服务) 可以把基础的表数据直接导出,然后导入到自己新搭建的项目里去。
具体的数据包含:
应用数据:sys_application、sys_application_group
页面菜单:sys_page、sys_menu
角色数据:sys_role 、sys_role_menu、sys_data_authority_rule
用户组数据:sys_group
组织数据:organization_type、organization
字典数据:sys_dict_type、sys_dict_value
国际化数据:language、lang_value
注意:
该功能只能应用于第一次初始化数据,业务项目的数据库是空的情况,否则id可能会冲突。后期会优化成可以增量插入的方式。