当前位置:   article > 正文

spring boot数据导出excel_springboot workbook fileoutputstream 导出excel文件示例代码

springboot workbook fileoutputstream 导出excel文件示例代码?

Controller:

  1. @PostMapping(value = "/export",
  2. produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE, MediaType.APPLICATION_JSON_VALUE})
  3. public void RApiExport(HttpServletResponse response, @RequestBody SearchListReqDto reqDto) throws Exception {
  4. rapiSearchConfigService.exportData(response, reqDto);
  5. }

service

  1. public void exportData(HttpServletResponse response, SearchListReqDto reqDto) throws IOException, IllegalAccessException {
  2. //excel对应多sheet实体类
  3. ExportRApiDataTemplate exportRApiDataTemplate = new ExportRApiDataTemplate();
  4. String statisticalStart = reqDto.getStatisticalStart();
  5. String statisticalEnd = reqDto.getStatisticalEnd();
  6. List<String> keywords = getKeywords(reqDto);
  7. List<SearchUserInfo> searchUserInfoList = new ArrayList<>();
  8. List<RapiSearchUser> searchUserList = rapiSearchUserDao.selectByCreateTime(statisticalStart, statisticalEnd, null, null, keywords);
  9. searchUserList.forEach(r -> {
  10. SearchUserInfo searchUserInfo = BeanConvertUtils.convertTo(r, SearchUserInfo::new);
  11. searchUserInfo.setCreateTime(DateUtil.toString(r.getCreateTime(), DateUtil.yyyy_MM_ddHHmmss_format));
  12. searchUserInfo.setUserHomePage(getUserShareUrl(r.getSearchUserInfo()));
  13. searchUserInfoList.add(searchUserInfo);
  14. });
  15. exportRApiDataTemplate.setSearchUserInfoList(searchUserInfoList);
  16. String nowDate = DateUtil.toString(new Date(), DateUtil.yyMMddHHmmss_format);
  17. //调用工具类导出
  18. EasyPoiUtils.exportMultiSheetWorkbook(nowDate + "RApi数据统计", exportRApiDataTemplate, response);
  19. }

excel导出模版对应实体类(注:子类不序列化会抛错)

  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. @Accessors(chain = true)
  5. public class ExportRApiDataTemplate {
  6. @SheetName(name = "人员信息")
  7. private List<SearchUserInfo> searchUserInfoList;
  8. /* @SheetName(name = "帖子信息")
  9. private List<SearchPostsInfo> searchPostsInfoList;
  10. @SheetName(name = "标签信息")
  11. private List<SearchHashTagInfo> searchHashTagInfoList;
  12. */
  13. }
  1. @JsonIgnoreProperties(ignoreUnknown = true)
  2. @Data
  3. public class SearchUserInfo implements Serializable {
  4. @Excel(name = "用户id")
  5. private String uid;
  6. @Excel(name = "用户名称",width = 30)
  7. private String name;
  8. @Excel(name = "已关注数量")
  9. private String followingCount;
  10. @Excel(name = "点赞数")
  11. private String totalFavorited;
  12. @Excel(name = "粉丝数量")
  13. private String followerCount;
  14. @Excel(name = "insId")
  15. private String insId;
  16. @Excel(name = "邮箱")
  17. private String email;
  18. @Excel(name = "用户主页链接")
  19. private String userHomePage;
  20. @Excel(name = "统计时间")
  21. private String createTime;
  22. @Excel(name = "数据抓取关键字",width = 50)
  23. private String dataSource;
  24. }

EasyPoiUtils 工具类

  1. package com.seezoon.admin.modules.sys.utils;
  2. import cn.afterturn.easypoi.excel.ExcelExportUtil;
  3. import cn.afterturn.easypoi.excel.ExcelImportUtil;
  4. import cn.afterturn.easypoi.excel.entity.ExportParams;
  5. import cn.afterturn.easypoi.excel.entity.ImportParams;
  6. import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
  7. import cn.afterturn.easypoi.exception.excel.ExcelExportException;
  8. import cn.afterturn.easypoi.exception.excel.ExcelImportException;
  9. import com.google.common.collect.Lists;
  10. import com.google.common.collect.Maps;
  11. import com.seezoon.admin.modules.sys.dto.excel.kol.SheetName;
  12. import org.apache.commons.lang3.StringUtils;
  13. import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
  14. import org.apache.poi.hssf.usermodel.HSSFRichTextString;
  15. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  16. import org.apache.poi.ss.usermodel.*;
  17. import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
  18. import org.apache.poi.xssf.usermodel.XSSFRichTextString;
  19. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  20. import org.slf4j.Logger;
  21. import org.slf4j.LoggerFactory;
  22. import org.springframework.web.multipart.MultipartFile;
  23. import javax.servlet.http.HttpServletResponse;
  24. import java.io.BufferedOutputStream;
  25. import java.io.File;
  26. import java.io.IOException;
  27. import java.io.OutputStream;
  28. import java.lang.reflect.Field;
  29. import java.lang.reflect.ParameterizedType;
  30. import java.lang.reflect.Type;
  31. import java.net.URLEncoder;
  32. import java.util.*;
  33. import java.util.zip.ZipEntry;
  34. import java.util.zip.ZipOutputStream;
  35. /**
  36. * @Classname EasyPoiUtils
  37. * @Description
  38. * @Date 2023/8/31 11:59
  39. * @Created by jyl
  40. */
  41. public class EasyPoiUtils {
  42. static final Logger logger = LoggerFactory.getLogger(EasyPoiUtils.class);
  43. private static final String XLS = "xls";
  44. private static final String XLSX = "xlsx";
  45. private static final String SPLIT = ".";
  46. public static void newExportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response){
  47. newExport(list, fileName, response);
  48. }
  49. private static void newDownLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
  50. try {
  51. response.setCharacterEncoding("UTF-8");
  52. response.setHeader("content-Type", "application/vnd.ms-excel");
  53. response.setHeader("Content-Disposition",
  54. "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
  55. workbook.write(response.getOutputStream());
  56. } catch (IOException e) {
  57. throw new RuntimeException(e.getMessage());
  58. }
  59. }
  60. private static void newExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
  61. Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
  62. if (workbook != null);
  63. newDownLoadExcel(fileName, response, workbook);
  64. }
  65. public static <T> List<T> newImportExcelMore(MultipartFile file, Class<T> pojoClass, ImportParams params){
  66. if (file == null){
  67. return null;
  68. }
  69. List<T> list = null;
  70. try {
  71. list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
  72. }catch (NoSuchElementException e){
  73. throw new RuntimeException("excel文件不能为空");
  74. } catch (Exception e) {
  75. throw new RuntimeException(e.getMessage());
  76. }
  77. return list;
  78. }
  79. public static Workbook newGetWorkbook(MultipartFile file) {
  80. Workbook workbook=null;
  81. try {
  82. // 获取Excel后缀名
  83. String fileName = file.getOriginalFilename();
  84. if (StringUtils.isEmpty(fileName) || fileName.lastIndexOf(SPLIT) < 0) {
  85. logger.warn("解析Excel失败,因为获取到的Excel文件名非法!");
  86. return null;
  87. }
  88. String fileType = fileName.substring(fileName.lastIndexOf(SPLIT) + 1, fileName.length());
  89. // 获取Excel工作簿
  90. if (fileType.equalsIgnoreCase(XLS)) {
  91. workbook = new HSSFWorkbook(file.getInputStream());
  92. } else if (fileType.equalsIgnoreCase(XLSX)) {
  93. workbook = new XSSFWorkbook(file.getInputStream());
  94. }
  95. } catch (IOException e) {
  96. e.printStackTrace();
  97. }
  98. return workbook;
  99. }
  100. public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response) {
  101. ExportParams exportParams = new ExportParams(title, sheetName);
  102. exportParams.setCreateHeadRows(isCreateHeader);
  103. defaultExport(list, pojoClass, fileName, response, exportParams);
  104. }
  105. /**
  106. * 导出excel
  107. *
  108. * @param list 数据list
  109. * @param title 标题
  110. * @param sheetName sheet名称
  111. * @param pojoClass 实体class
  112. * @param fileName 文件名
  113. * @param response 响应
  114. */
  115. public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) {
  116. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=GBK");
  117. try {
  118. response.setHeader("content-disposition",
  119. "attachment;filename=" + java.net.URLEncoder.encode(fileName, "GBK")
  120. + ";filename*=GBK''" + java.net.URLEncoder.encode(fileName, "GBK"));
  121. } catch (Exception e) {
  122. // ...
  123. }
  124. defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));
  125. }
  126. /**
  127. * 导出excel
  128. *
  129. * @param list 多个Map key title 对应表格Title key entity 对应表格对应实体 key data
  130. * @param fileName 标题
  131. * @param response 响应
  132. */
  133. public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
  134. defaultExport(list, fileName, response);
  135. }
  136. /**
  137. * 导出多个excel
  138. *
  139. * @param workbooks 多个excel文件 通过ExcelExportUtil.exportExcel往workbooks内放入excel
  140. * @param fileNames 文件名 每个excel文件的名称顺序必须一致且名称请务必保证不重复
  141. * @param fileName 压缩包文件名
  142. * @param response 标题
  143. */
  144. public static void exportExcels(List<Workbook> workbooks, List<String> fileNames, String fileName, HttpServletResponse response) {
  145. try {
  146. response.setHeader("Content-Disposition",
  147. "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".zip");
  148. OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
  149. ZipOutputStream zipOut = new ZipOutputStream(toClient);
  150. for (int i = 0; i < workbooks.size(); i++) {
  151. ZipEntry entry = new ZipEntry(fileNames.get(i) + ".xls");
  152. zipOut.putNextEntry(entry);
  153. workbooks.get(i).write(zipOut);
  154. }
  155. zipOut.flush();
  156. zipOut.close();
  157. } catch (IOException e) {
  158. throw new ExcelExportException(e.getMessage());
  159. }
  160. }
  161. /**
  162. * 导出excel
  163. *
  164. * @param list 数据list
  165. * @param pojoClass 实体class
  166. * @param fileName 文件名
  167. * @param response 响应
  168. */
  169. private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
  170. Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
  171. downLoadExcel(fileName, response, workbook);
  172. }
  173. private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
  174. try {
  175. response.setCharacterEncoding("UTF-8");
  176. response.setHeader("content-Type", "application/vnd.ms-excel");
  177. response.setHeader("Content-Disposition",
  178. "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
  179. workbook.write(response.getOutputStream());
  180. workbook.close();
  181. } catch (IOException e) {
  182. throw new ExcelImportException(e.getMessage());
  183. }
  184. }
  185. private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
  186. Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
  187. downLoadExcel(fileName, response, workbook);
  188. }
  189. public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
  190. if (StringUtils.isBlank(filePath)) {
  191. return null;
  192. }
  193. ImportParams params = new ImportParams();
  194. params.setTitleRows(titleRows);
  195. params.setHeadRows(headerRows);
  196. List<T> list = null;
  197. try {
  198. list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
  199. } catch (NoSuchElementException e) {
  200. throw new ExcelImportException("模板不能为空");
  201. } catch (Exception e) {
  202. e.printStackTrace();
  203. throw new ExcelImportException(e.getMessage());
  204. }
  205. return list;
  206. }
  207. public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
  208. if (file == null) {
  209. return null;
  210. }
  211. ImportParams params = new ImportParams();
  212. params.setTitleRows(titleRows);//标题占几行,从哪行开始读取
  213. params.setHeadRows(headerRows);//header占几行
  214. params.setSheetNum(1);
  215. List<T> list = null;
  216. try {
  217. list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
  218. } catch (NoSuchElementException e) {
  219. throw new ExcelImportException("excel文件不能为空");
  220. } catch (Exception e) {
  221. throw new ExcelImportException(e.getMessage());
  222. }
  223. return list;
  224. }
  225. /**
  226. * 多Sheet导出,不需要批注
  227. * @param fileName 文件名
  228. * @param exportDataSet 导出的类对象
  229. * @param response
  230. * @throws IllegalAccessException
  231. * @throws IOException
  232. */
  233. public static <T> void exportMultiSheetWorkbook(String fileName,T exportDataSet, HttpServletResponse response) throws IOException, IllegalAccessException {
  234. exportMultiSheetWorkbook(fileName,exportDataSet,response,null);
  235. }
  236. /**
  237. * 多Sheet导出,需要批注
  238. * @param fileName 文件名
  239. * @param exportDataSet 导出的类对象
  240. * @param response
  241. * @throws IllegalAccessException
  242. * @throws IOException
  243. */
  244. public static <T> void exportMultiSheetWorkbook(String fileName,T exportDataSet, HttpServletResponse response,String remake) throws IllegalAccessException, IOException {
  245. // 多个sheet配置参数
  246. final List<Map<String, Object>> sheetsList = Lists.newArrayList();
  247. Class<?> aClass = exportDataSet.getClass();
  248. Field[] declaredFields = aClass.getDeclaredFields();
  249. for (Field field : declaredFields) {
  250. field.setAccessible(true);
  251. SheetName annotation = field.getAnnotation(SheetName.class);
  252. final String sheetName = annotation.name();
  253. Map<String, Object> exportMap = Maps.newHashMap();
  254. final ExportParams exportParams = new ExportParams(null, sheetName);
  255. // 以下3个参数为API中写死的参数名 分别是sheet配置/导出类(注解定义)/数据集
  256. exportMap.put("title", exportParams);
  257. // 获取list<?>中?的泛型
  258. if (field.getType().isAssignableFrom(List.class)){
  259. Type fc = field.getGenericType(); //如果是List类型,得到其Generic的类型
  260. if(fc instanceof ParameterizedType){
  261. ParameterizedType pt = (ParameterizedType) fc;
  262. //得到泛型里的class类型对象。
  263. Class genericClazz = (Class)pt.getActualTypeArguments()[0];
  264. exportMap.put("entity", genericClazz);
  265. }
  266. exportMap.put("data", field.get(exportDataSet));
  267. }else {
  268. exportMap.put("entity", field.getType());
  269. exportMap.put("data", new ArrayList<>(Collections.singletonList(field.get(exportDataSet))));
  270. }
  271. // 加入多sheet配置列表
  272. sheetsList.add(exportMap);
  273. }
  274. // 导出文件
  275. // 核心方法:导出含多个sheet的excel文件 【注意,该方法第二个参数必须与上述的ExportParams对象指定的导出类型一致,默认ExcelType.HSSF格式,否则执行此方法时会报错!!!】
  276. final Workbook workbook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);
  277. // 添加批注格式 :0#姓名不能为空__1#学生性别 1:男 2:女__2#出生日期:yyyy-MM-dd__3#图片不能为空
  278. if(StringUtils.isNotBlank(remake)){
  279. buildComment(workbook,0,remake);
  280. }
  281. response.setCharacterEncoding("UTF-8");
  282. response.setHeader("content-Type", "application/vnd.ms-excel");
  283. response.setHeader("Content-Disposition",
  284. "attachment;filename=" + URLEncoder.encode(fileName + ".xls", "UTF-8"));
  285. workbook.write(response.getOutputStream());
  286. // 写完数据关闭流
  287. workbook.close();
  288. }
  289. public static void buildComment(Workbook workbook, int titleRowsIndex, String commentStr) {
  290. Sheet sheet = workbook.getSheetAt(0);
  291. //创建一个图画工具
  292. Drawing<?> drawing = sheet.createDrawingPatriarch();
  293. Row row = sheet.getRow(titleRowsIndex);
  294. if (StringUtils.isNotBlank(commentStr)) {
  295. //解析批注,并传换成map
  296. Map<Integer, String> commentMap = getCommentMap(commentStr);
  297. for (Map.Entry<Integer, String> entry : commentMap.entrySet()) {
  298. Cell cell = row.getCell(entry.getKey());
  299. //创建批注
  300. Comment comment = drawing.createCellComment(newClientAnchor(workbook));
  301. //输入批注信息
  302. comment.setString(newRichTextString(workbook, entry.getValue()));
  303. //将批注添加到单元格对象中
  304. cell.setCellComment(comment);
  305. if (entry.getValue().contains("必填项")){
  306. //设置单元格背景颜色
  307. CellStyle cellStyle = workbook.createCellStyle();
  308. //通过workbook获得文字处理类
  309. Font font = workbook.createFont();
  310. font.setColor(Font.COLOR_RED);
  311. //水平居中
  312. cellStyle.setAlignment(HorizontalAlignment.CENTER);
  313. //垂直居中
  314. cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  315. cellStyle.setFont(font);
  316. cell.setCellStyle(cellStyle);
  317. }
  318. }
  319. }
  320. }
  321. /**
  322. * 批注信息,默认解析:批注#列索引,比如用户名不允许重复#0。可覆盖此方法,解析自定义的批注格式
  323. *
  324. * @param commentStr 当前行的所有批注信息
  325. * @return key:列索引,value:对应列的所有批注信息
  326. */
  327. protected static Map<Integer, String> getCommentMap(String commentStr) {
  328. //每行的所有单元格的批注都在commentStr里,并用”__”分隔
  329. String[] split = commentStr.split("__");
  330. Map<Integer, String> commentMap = new HashMap<>();
  331. for (String msg : split) {
  332. String[] cellMsg = msg.split("#");
  333. //如果当前列没有批注,会将该列的索引作为key存到map里;已有批注,以“,“分隔继续拼接
  334. int cellIndex = Integer.parseInt(cellMsg[0]);
  335. if (commentMap.get(cellIndex) == null) {
  336. commentMap.put(cellIndex, cellMsg[1]);
  337. } else {
  338. commentMap.replace(cellIndex, commentMap.get(cellIndex) + "," + cellMsg[1]);
  339. }
  340. }
  341. return commentMap;
  342. }
  343. private static ClientAnchor newClientAnchor(Workbook workbook) {
  344. //xls
  345. if (workbook instanceof HSSFWorkbook) {
  346. return new HSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6);
  347. }
  348. //xlsx
  349. else {
  350. return new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6);
  351. }
  352. }
  353. private static RichTextString newRichTextString(Workbook workbook, String msg) {
  354. //xls
  355. if (workbook instanceof HSSFWorkbook) {
  356. return new HSSFRichTextString(msg);
  357. }
  358. //xlsx
  359. else {
  360. return new XSSFRichTextString(msg);
  361. }
  362. }
  363. }

若需要合并单元格可使用@ExcelCollection注解 

注:标记该注解的类型必须是list,且list类型里的属性须有@Excel注解标记

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/536773
推荐阅读
相关标签
  

闽ICP备14008679号