简介
里面包括了excel导出生成byte,导出excel表,导出多个sheet的excel表,导出zip压缩文件,导出自定义表头excel等。demo只是写了两个简单的例子。如果没有看懂的请私信。
导出场景工具
- 导出到本地
/**
* 生成在指定文件夹中
*
* @param outputDir 文件夹位置
* @param zipName 压缩包名字
* @param data 需要输出的文件流
* @throws IOException 1
*/
public static void writeByteArrayToFile(String outputDir, String zipName, byte[] data) throws IOException {
String filePath = outputDir + File.separator + zipName;
FileOutputStream fos = new FileOutputStream(filePath);
fos.write(data);
fos.close();
}
- 导出到前端
/**
* 导出到前端
*
* @param response http相应
* @param fileName 导出的文件名字
* @param data 需要输出的文件流
* @throws IOException 1
*/
public static void writeByteArrayToResponse(HttpServletResponse response, String fileName, byte[] data) throws IOException {
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.getOutputStream().write(data);
}
单个excel导出
生成excel文件流,再将生成好的文件流,通过自己不同的场景进行导出即可。
/**
* 导出生成excel文件流 一个列表一个excel
*
* @param exportList 需要导出的列表
* @param sheetName sheet名字
* @param tClass 导出列表的类型
* @param <T> 导出列表的类型
* @return excel流 用于后面导出用
*/
public static <T> byte[] exportExcel(List<T> exportList, String sheetName, Class<T> tClass) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();// 创建一个 ByteArrayOutputStream 对象,这个对象将用于存储生成的 Excel 文件的字节。
ExcelWriter excelWriter = EasyExcel.write(outputStream, tClass).build(); // 使用 EasyExcel 创建一个 ExcelWriter 对象,这个对象将用于写入 Excel 文件。outputStream 是写入的目标,tClass 是列表中元素的类型。
// 创建自定义样式策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();// 创建一个 WriteCellStyle 对象,这个对象将用于定义 Excel 单元格的样式。
// 设置自动换行
contentWriteCellStyle.setWrapped(true);// 设置 contentWriteCellStyle 的 wrapped 属性为 true,这意味着如果单元格的内容超过了列宽,内容将自动换行。
HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(new WriteCellStyle(), contentWriteCellStyle);
WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).registerWriteHandler(horizontalCellStyleStrategy).build();
// 设置列宽,15表示15个字符宽度
// writeSheet.setColumnWidthMap(Collections.singletonMap(0, 15));
excelWriter.write(exportList, writeSheet); // 将 exportList 的数据写入 writeSheet。
excelWriter.finish(); // 完成写入操作。
try {
outputStream.close();// 关闭 outputStream。
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return outputStream.toByteArray(); // 返回生成的 Excel 文件的字节数组。
}
public static byte[] exportTxt(String str, String fileName) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
outputStream.write(str.getBytes()); // 将字符串转换为字节数组并写入outputStream
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return outputStream.toByteArray();
}
举个例子
下面的例子是将生成好的excel流文件,导出到了前端。
byte[] excel = ExportFileUtils.exportExcel(exportDataList, "sheet", ReportScoreExportData.class);
try {
ExportFileUtils.writeByteArrayToResponseExcel(response, excelName + ".xlsx", excel);
} catch (IOException e) {
throw new RuntimeException(e);
}
扩展
基本导出逻辑就是先将列表转换成excel流,再将流进行导出处理。下面介绍几种项目中常用的导出方式
- 多个sheet导出
/**
* 多个列表放到不同的sheet中 多个列表一个excel不同的sheet
*
* @param dataMap 多个列表
* @param type 导出列表的类型
* @param <T> 导出列表的类型
* @return excel流 用于后面导出用
*/
public static <T> byte[] exportExcel(Map<String, List<T>> dataMap, Class<T> type) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ExcelWriter excelWriter = EasyExcel.write(outputStream, type).build();
// 创建自定义样式策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
// 设置自动换行
contentWriteCellStyle.setWrapped(true);
HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(new WriteCellStyle(), contentWriteCellStyle);
// 对于 dataMap 中的每个条目,创建一个新的 WriteSheet 并写入数据
for (Map.Entry<String, List<T>> entry : dataMap.entrySet()) {
String sheetName = entry.getKey();
List<T> dataList = entry.getValue();
WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).registerWriteHandler(horizontalCellStyleStrategy).build();
// 设置列宽,15表示15个字符宽度
writeSheet.setColumnWidthMap(Collections.singletonMap(0, 15));
excelWriter.write(dataList, writeSheet);
}
excelWriter.finish();
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return outputStream.toByteArray();
}
}
- 多个excel封装成压缩包
思路:将多个excel流,放到工具中
/**
* 将生成的文件打压缩包
*
* @param fileData excel文件流
* @param nameList 名称列表
* @return 压缩包流
* @throws IOException 1
*/
public static byte[] zipFiles(List<byte[]> fileData, List<String> nameList) throws IOException {
ByteArrayOutputStream zipOutput = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(zipOutput);
for (int i = 0; i < fileData.size(); i++) {
byte[] data = fileData.get(i);
String fileName = nameList.get(i) + ".xlsx";
ZipEntry zipEntry = new ZipEntry(fileName);
zipOut.putNextEntry(zipEntry);
zipOut.write(data, 0, data.length);
zipOut.closeEntry();
}
zipOut.close();
zipOutput.close();
return zipOutput.toByteArray();
}
- 自定义表头
```java
/**
* 自定义表头导出
*
* @param title
* @param headers
* @param data
* @param response
* @throws IOException
*/
public static void exportExcelDynamicHeaderSingle(String fileName, String title, Map<String, String> headers,
List<Map<String, String>> data, HttpServletResponse response) throws IOException {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet1");
// 创建标题行 不需要标题 所有行上移
Integer titleRowNum = -1;
if (StringUtils.isNotBlank(title)) { // 有标题行
titleRowNum = 0;
Row titleRow = sheet.createRow(titleRowNum);
Cell titleCell = titleRow.createCell(titleRowNum);
titleCell.setCellValue(title);
}
// 创建表头行
Row headerRow = sheet.createRow(titleRowNum + 1);
int cellIndex = 0;
for (Map.Entry<String, String> entry : headers.entrySet()) {
Cell cell = headerRow.createCell(cellIndex++);
cell.setCellValue(entry.getValue());
}
// 创建数据行
for (int i = 0; i < data.size(); i++) {
Row dataRow = sheet.createRow(i + titleRowNum + 2); // 数据行从第三行开始
Map<String, String> rowData = data.get(i);
cellIndex = 0;
for (String header : headers.keySet()) {
Cell cell = dataRow.createCell(cellIndex++);
cell.setCellValue(rowData.get(header));
}
}
String dateTimeNow = DateUtils.dateTimeNow();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName + dateTimeNow + ".xlsx", "UTF-8"));
workbook.write(response.getOutputStream());
}
小结
后面如果用到了一些关系到excel导出的,还会继续更新的。
最近再整理多层动态表头的excel,如果大家有好方法,希望可以学习一下,感谢。