EasyPoi介绍:
利用注解的方式简化了Excel 、Word 、PDF等格式的导入导出 ,而且是百万级数据的导入导出 。EasyPoi官方网址:EasyPoi教程_V1.0 (mydoc.io) 。下面我写了一个测试用例 ,真的是很方便 ,可以利用注解自动完成单元格的合并 ,设置单元格宽度 、设置字符替换 、并且可以很好的完成实体类之间一对一 、一对多关系的处理
不卖关子 ,事先说明百万级大数据操作使用:导入(importExcelBySax) ,导出(exportBigExcel)
导入依赖
实体对象
/**
* 免打扰手机号
*
* @author Mark sunlightcs@gmail.com
* @since 1.0.0
*/
@Data
public class NonIntrusiveExcel {
@Excel(name = "手机号码", width = 20)
@NotNull
private String phone;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NonIntrusiveExcel that = (NonIntrusiveExcel) o;
return phone.equals(that.phone);
}
@Override
public int hashCode() {
return Objects.hash(phone);
}
}
导入导出工具类
/**
* excel工具类
*
* excel中xls和xlsx的区别是:
* 1 、文件格式不同 。xls是一个特有的二进制格式 ,其核心结构是复合文档类型的结构 ,而xlsx的核心结构是XML类型的结构 ,采用的是基于 XML 的压缩方式,使其占用的空间更小 。xlsx 中最后一个 x 的意义就在于此 。
* 2 、版本不同 。xls是excel2003及以前版本生成的文件格式 ,而xlsx是excel2007及以后版本生成的文件格式 。
* 3 、兼容性不同 。xlsx格式是向下兼容的 ,可兼容xls格式 。
*
* @author Mark sunlightcs@gmail.com
*/
public class ExcelUtils {
/**
* Excel导入
*
* @param request request
* @param pojoClass 对象Class
*/
public static List importExcel(HttpServletRequest request, Class<?> pojoClass)
throws IOException {
MultipartHttpServletRequest multipartRequest =
(MultipartHttpServletRequest) request;
MultipartFile file = multipartRequest.getFile("file"
);
if (file ==
null) {
throw new RenException("未找到上传的文件!"
);
}
ImportParams params =
new ImportParams();
params.setHeadRows(1
);
params.setNeedVerify(true);
// 开启校验规则
List targetList =
null;
try {
System.out.println("正在
读取文件: " + file.getOriginalFilename() + ",开始导入数据。"
);
targetList =
ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
} catch (Exception e) {
e.printStackTrace();
} finally {
file.getInputStream().close();
}
return targetList;
}
/**
* Excel大数据导入
*
* @param request request
* @param pojoClass 对象Class
*/
public static Set importBigExcel(HttpServletRequest request, Class<?> pojoClass)
throws IOException {
MultipartHttpServletRequest multipartRequest =
(MultipartHttpServletRequest) request;
MultipartFile file = multipartRequest.getFile("file"
);
if (file ==
null) {
throw new RenException("未找到上传的文件!"
);
}
ImportParams params =
new ImportParams();
params.setHeadRows(1
);
params.setNeedVerify(true);
// 开启校验规则
Set targetList =
new HashSet();
// 添加set集合过滤去重元素
try {
System.out.println("正在读取文件: " + file.getOriginalFilename() + " ,开始导入数据 。"
);
ExcelImportUtil.importExcelBySax(file.getInputStream(), pojoClass, params, new IReadHandler() {
@Override
public void handler(Object o) {
targetList.add(o);
}
@Override
public void doAfterAll() {
}
});
} catch (Exception e) {
e.printStackTrace();
} finally {
file.getInputStream().close();
}
return targetList;
}
/**
* Excel导出
*
* @param response response
* @param fileName 文件名
* @param list 数据List
* @param pojoClass 对象Class
*/
public static void exportExcel(HttpServletResponse response, String fileName, Collection<?>
list,
Class<?> pojoClass)
throws IOException {
if (StringUtils.isBlank(fileName)) {
//当前日期
fileName = DateUtil.formatDatetime(
new Date());
}
// 设置导出格式为xlsx ,默认xlsx
ExportParams exportParams =
new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook =
ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
response.setCharacterEncoding("UTF-8"
);
response.setHeader("content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
);
// response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition"
,
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx"
);
ServletOutputStream out =
response.getOutputStream();
workbook.write(out);
out.flush();
}
/**
* Excel大数据导出
*
* @param list 数据List
* @param pojoClass 对象Class
*/
public static byte[] exportBigExcelByte(Collection<?> list, Class<?> pojoClass)
throws IOException {
Workbook workbook;
// 设置导出单sheet页最大一百万行数据
ExportParams exportParams =
new ExportParams();
exportParams.setMaxNum(1000000
);
exportParams.setType(ExcelType.XSSF);
workbook = ExcelExportUtil.exportBigExcel(exportParams, pojoClass, (queryParams, num) ->
{
// 只导出一次,第二次返回null终止循环
if (((
int) queryParams) ==
num) {
return null;
}
System.out.println("正在进行大数据量导出 ,条数: " +
list.size());
return Arrays.asList(list.toArray());
}, 2
);
ByteArrayOutputStream bos =
new ByteArrayOutputStream();
workbook.write(bos);
bos.close();
byte[] bytes =
bos.toByteArray();
return bytes;
}
/**
* Excel导出 ,先sourceList转换成List<targetClass> ,再导出
*
* @param response response
* @param fileName 文件名
* @param sourceList 原数据List
* @param targetClass 目标对象Class
*/
public static void exportExcelToTarget(HttpServletResponse response, String fileName, Collection<?>
sourceList,
Class<?> targetClass)
throws Exception {
List targetList =
new ArrayList<>
(sourceList.size());
for (Object source : sourceList) {
Object target =
targetClass.newInstance();
BeanUtils.copyProperties(source, target);
targetList.add(target);
}
exportExcel(response, fileName, targetList, targetClass);
}
/**
* Excel生成
*
* @param response response
* @param fileName 文件名
*/
public static void mkdirExcel(HttpServletResponse response, String fileName,
Workbook workbook) throws IOException {
if (StringUtils.isBlank(fileName)) {
//当前日期
fileName = DateUtil.formatDatetime(
new Date());
}
response.setCharacterEncoding("UTF-8"
);
response.setHeader("content-Type", "application/vnd.ms-excel"
);
response.setHeader("Content-Disposition"
,
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls"
);
ServletOutputStream out =
response.getOutputStream();
workbook.write(out);
out.flush();
}
/**
* XSSF
* excel添加下拉数据校验
*
* @param workbook 哪个 sheet 页添加校验
* @param dataSource 数据源数组
* @param col 第几列校验(0开始)
* @return
*/
public static void createXssfSelected(Workbook workbook, String[] dataSource,
int col) {
Sheet sheet = workbook.getSheetAt(0
);
CellRangeAddressList cellRangeAddressList =
new CellRangeAddressList(1, 65535
, col, col);
DataValidationHelper helper =
sheet.getDataValidationHelper();
DataValidationConstraint constraint =
helper.createExplicitListConstraint(dataSource);
DataValidation dataValidation =
helper.createValidation(constraint, cellRangeAddressList);
//处理Excel兼容性问题
if (dataValidation
instanceof XSSFDataValidation) {
dataValidation.setSuppressDropDownArrow(true);
dataValidation.setShowErrorBox(true);
} else {
dataValidation.setSuppressDropDownArrow(false);
}
dataValidation.setEmptyCellAllowed(true);
dataValidation.setShowPromptBox(true);
dataValidation.createPromptBox("提示", "只能选择下拉框里面的数据"
);
sheet.addValidationData(dataValidation);
}
}
接口调用
@RestController
@RequestMapping("/app/nonIntrusive")
@Slf4j
public class NonIntrusiveController {
@Autowired
private NonIntrusiveService appNonIntrusiveService;
@PostMapping(value = "/importAndExportFilter")
@LogOperation("免打扰过滤")
@RequiresPermissions("app:nonIntrusive:filter")
public byte[] importFilter(HttpServletRequest request) throws Exception {
long startTime = System.currentTimeMillis();
// 读取excel文件内容转成集合
Set importSet = ExcelUtils.importBigExcel(request, NonIntrusiveExcel.class);
log.info("已读取文件内容条数:{}, 总共耗时:{} 毫秒", importSet.size(), System.currentTimeMillis() - startTime);
startTime = System.currentTimeMillis();
// 读取数据表列表集合
Set phoneSet = appNonIntrusiveService.listExcel();
log.info("已加载存储的免打扰号码库总条数:{}, 总共耗时:{} 毫秒", phoneSet.size(), System.currentTimeMillis() - startTime);
startTime = System.currentTimeMillis();
// Set排除已存在的集合数据
importSet.removeAll(phoneSet);
log.info("已完成过滤免打扰号码后的总条数:{}, 总共耗时:{} 毫秒", importSet.size(), System.currentTimeMillis() - startTime);
// 进行大数据excel导出
return ExcelUtils.exportBigExcelByte(importSet, NonIntrusiveExcel.class);
}
@GetMapping(value = "/exportTemplate")
public void export(HttpServletResponse response) throws Exception {
ExcelUtils.exportExcelToTarget(response, null, new ArrayList<>(), NonIntrusiveExcel.class);
}
}
声明:本站所有文章 ,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织 ,在未征得本站同意时 ,禁止复制 、盗用、采集 、发布本站内容到任何网站 、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。