日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

SpringBoot中EasyExcel實(shí)現(xiàn)Excel文件的導(dǎo)入導(dǎo)出

瀏覽:173日期:2022-06-16 18:07:41

前言

在我們?nèi)粘5拈_(kāi)發(fā)過(guò)程中經(jīng)常會(huì)使用Excel文件的形式來(lái)批量地上傳下載系統(tǒng)數(shù)據(jù),我們最常用的工具是Apache poi,但是如果數(shù)據(jù)到底上百萬(wàn)時(shí),將會(huì)造成內(nèi)存溢出的問(wèn)題,那么我們?cè)趺慈?shí)現(xiàn)百萬(wàn)數(shù)據(jù)批量導(dǎo)入導(dǎo)出。

正文

Easyexcel

Easyexcel 是阿里巴巴的開(kāi)源項(xiàng)目,用來(lái)優(yōu)化Excel文件處理過(guò)程:

poi消耗內(nèi)存嚴(yán)重:Java解析、生成Excel比較有名的框架有Apache poi、jxl。但他們都存在一個(gè)嚴(yán)重的問(wèn)題就是非常的耗內(nèi)存,poi有一套SAX模式的API可以一定程度的解決一些內(nèi)存溢出的問(wèn)題,但poi還是有一些缺陷,比如07版Excel解壓縮以及解壓后存儲(chǔ)都是在內(nèi)存中完成的,內(nèi)存消耗依然很大。 easyexcel針對(duì)內(nèi)存做出了優(yōu)化:重寫(xiě)了poi對(duì)07版Excel的解析,能夠原本一個(gè)3M的excel用POI sax依然需要100M左右內(nèi)存降低到幾M,并且再大的excel不會(huì)出現(xiàn)內(nèi)存溢出。

SpringBoot中EasyExcel實(shí)現(xiàn)Excel文件的導(dǎo)入導(dǎo)出

SpringBoot+ EasyExcel實(shí)現(xiàn)Excel文件的導(dǎo)入導(dǎo)出

導(dǎo)入依賴

<!--lombok--><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.2</version> <optional>true</optional></dependency><!--easyExcel--><dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>1.1.2-beat1</version></dependency><!--fastjson--><dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <exclusions> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </exclusion> </exclusions></dependency><dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId></dependency>

為了防止Excel文件被破壞在pom.xml添加以下內(nèi)容

<build> <plugins> <!-- 讓maven不編譯xls文件,但仍將其打包 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration><nonFilteredFileExtensions> <nonFilteredFileExtension>xls</nonFilteredFileExtension> <nonFilteredFileExtension>xlsx</nonFilteredFileExtension></nonFilteredFileExtensions> </configuration> </plugin> </plugins></build>

application.propertis:配置文件

#temp filesproject.tmp.files.path=/Users/mac/Desktop/image/tmp/files/

在SpringBoot啟動(dòng)類添加臨時(shí)文件設(shè)置

@Value('${project.tmp.files.path}')public String filesPath;@BeanMultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); //設(shè)置路徑xxx factory.setLocation(filesPath); return factory.createMultipartConfig();}

ExcelUtil:Excel工具類

@Slf4jpublic class ExcelUtil { private static Sheet initSheet; static { initSheet = new Sheet(1, 0); initSheet.setSheetName('sheet'); //設(shè)置自適應(yīng)寬度 initSheet.setAutoWidth(Boolean.TRUE); } public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) { try { response.setCharacterEncoding('UTF-8'); response.setContentType('application/octet-stream;charset=utf-8'); response.setHeader('Content-Disposition', 'attachment;filename=' + URLEncoder.encode(fileName, 'UTF-8')); workbook.write(response.getOutputStream()); } catch (IOException e) { // throw new NormalException(e.getMessage()); } } /** * 讀取少于1000行數(shù)據(jù) * * @param filePath 文件絕對(duì)路徑 * @return */ public static List<Object> readLessThan1000Row(String filePath) { return readLessThan1000RowBySheet(filePath, null); } /** * 讀小于1000行數(shù)據(jù), 帶樣式 * filePath 文件絕對(duì)路徑 * initSheet : * sheetNo: sheet頁(yè)碼,默認(rèn)為1 * headLineMun: 從第幾行開(kāi)始讀取數(shù)據(jù),默認(rèn)為0, 表示從第一行開(kāi)始讀取 * clazz: 返回?cái)?shù)據(jù)List<Object> 中Object的類名 */ public static List<Object> readLessThan1000RowBySheet(String filePath, Sheet sheet) { if (!StringUtils.hasText(filePath)) { return null; } sheet = sheet != null ? sheet : initSheet; InputStream fileStream = null; try { fileStream = new FileInputStream(filePath); return EasyExcelFactory.read(fileStream, sheet); } catch (FileNotFoundException e) { log.info('找不到文件或文件路徑錯(cuò)誤, 文件:{}', filePath); } finally { try {if (fileStream != null) { fileStream.close();} } catch (IOException e) {log.info('excel文件讀取失敗, 失敗原因:{}', e); } } return null; } /** * 讀大于1000行數(shù)據(jù) * * @param filePath 文件覺(jué)得路徑 * @return */ public static List<Object> readMoreThan1000Row(String filePath) { return readMoreThan1000RowBySheet(filePath, null); } /** * 讀大于1000行數(shù)據(jù), 帶樣式 * * @param filePath 文件覺(jué)得路徑 * @return */ public static List<Object> readMoreThan1000RowBySheet(String filePath, Sheet sheet) { if (!StringUtils.hasText(filePath)) { return null; } sheet = sheet != null ? sheet : initSheet; InputStream fileStream = null; try { fileStream = new FileInputStream(filePath); ExcelListener excelListener = new ExcelListener(); EasyExcelFactory.readBySax(fileStream, sheet, excelListener); return excelListener.getDatas(); } catch (FileNotFoundException e) { log.error('找不到文件或文件路徑錯(cuò)誤, 文件:{}', filePath); } finally { try {if (fileStream != null) { fileStream.close();} } catch (IOException e) {log.error('excel文件讀取失敗, 失敗原因:{}', e); } } return null; } /** * 讀大于1000行數(shù)據(jù), 帶樣式 * * @return */ public static List<Object> readMoreThan1000RowBySheetFromInputStream(InputStream inputStream, Sheet sheet) { sheet = sheet != null ? sheet : initSheet; InputStream fileStream = null; ExcelListener excelListener = new ExcelListener(); EasyExcelFactory.readBySax(inputStream, sheet, excelListener); return excelListener.getDatas(); } /** * 生成excle * * @param filePath 絕對(duì)路徑 * @param data 數(shù)據(jù)源 * @param head 表頭 */ public static void writeBySimple(String filePath, List<List<Object>> data, List<String> head) { writeSimpleBySheet(filePath, data, head, null); } /** * 生成excle * * @param filePath 路徑 * @param data 數(shù)據(jù)源 * @param sheet excle頁(yè)面樣式 * @param head 表頭 */ public static void writeSimpleBySheet(String filePath, List<List<Object>> data, List<String> head, Sheet sheet) { sheet = (sheet != null) ? sheet : initSheet; if (head != null) { List<List<String>> list = new ArrayList<>(); head.forEach(h -> list.add(Collections.singletonList(h))); sheet.setHead(list); } OutputStream outputStream = null; ExcelWriter writer = null; try { outputStream = new FileOutputStream(filePath); writer = EasyExcelFactory.getWriter(outputStream); writer.write1(data, sheet); } catch (FileNotFoundException e) { log.error('找不到文件或文件路徑錯(cuò)誤, 文件:{}', filePath); } finally { try {if (writer != null) { writer.finish();}if (outputStream != null) { outputStream.close();} } catch (IOException e) {log.error('excel文件導(dǎo)出失敗, 失敗原因:{}', e); } } } /** * 生成excle * * @param filePath 路徑 * @param data 數(shù)據(jù)源 */ public static void writeWithTemplate(String filePath, List<? extends BaseRowModel> data) { writeWithTemplateAndSheet(filePath, data, null); } /** * 生成excle * * @param filePath 路徑 * @param data 數(shù)據(jù)源 * @param sheet excle頁(yè)面樣式 */ public static void writeWithTemplateAndSheet(String filePath, List<? extends BaseRowModel> data, Sheet sheet) { if (CollectionUtils.isEmpty(data)) { return; } sheet = (sheet != null) ? sheet : initSheet; sheet.setClazz(data.get(0).getClass()); OutputStream outputStream = null; ExcelWriter writer = null; try { outputStream = new FileOutputStream(filePath); writer = EasyExcelFactory.getWriter(outputStream); writer.write(data, sheet); } catch (FileNotFoundException e) { log.error('找不到文件或文件路徑錯(cuò)誤, 文件:{}', filePath); } finally { try {if (writer != null) { writer.finish();}if (outputStream != null) { outputStream.close();} } catch (IOException e) {log.error('excel文件導(dǎo)出失敗, 失敗原因:{}', e); } } } /** * 生成多Sheet的excle * * @param filePath 路徑 * @param multipleSheelPropetys */ public static void writeWithMultipleSheel(String filePath, List<MultipleSheelPropety> multipleSheelPropetys) { if (CollectionUtils.isEmpty(multipleSheelPropetys)) { return; } OutputStream outputStream = null; ExcelWriter writer = null; try { outputStream = new FileOutputStream(filePath); writer = EasyExcelFactory.getWriter(outputStream); for (MultipleSheelPropety multipleSheelPropety : multipleSheelPropetys) {Sheet sheet = multipleSheelPropety.getSheet() != null ? multipleSheelPropety.getSheet() : initSheet;if (!CollectionUtils.isEmpty(multipleSheelPropety.getData())) { sheet.setClazz(multipleSheelPropety.getData().get(0).getClass());}writer.write(multipleSheelPropety.getData(), sheet); } } catch (FileNotFoundException e) { log.error('找不到文件或文件路徑錯(cuò)誤, 文件:{}', filePath); } finally { try {if (writer != null) { writer.finish();}if (outputStream != null) { outputStream.close();} } catch (IOException e) {log.error('excel文件導(dǎo)出失敗, 失敗原因:{}', e); } } } /*********************匿名內(nèi)部類開(kāi)始,可以提取出去******************************/ @Data public static class MultipleSheelPropety { private List<? extends BaseRowModel> data; private Sheet sheet; } /** * 解析監(jiān)聽(tīng)器, * 每解析一行會(huì)回調(diào)invoke()方法。 * 整個(gè)excel解析結(jié)束會(huì)執(zhí)行doAfterAllAnalysed()方法 * * @author: chenmingjian * @date: 19-4-3 14:11 */ @Getter @Setter public static class ExcelListener extends AnalysisEventListener { private List<Object> datas = new ArrayList<>(); /** * 逐行解析 * object : 當(dāng)前行的數(shù)據(jù) */ @Override public void invoke(Object object, AnalysisContext context) { //當(dāng)前行 // context.getCurrentRowNum() if (object != null) {datas.add(object); } } /** * 解析完所有數(shù)據(jù)后會(huì)調(diào)用該方法 */ @Override public void doAfterAllAnalysed(AnalysisContext context) { //解析結(jié)束銷毀不用的資源 } } /************************匿名內(nèi)部類結(jié)束,可以提取出去***************************/}

CommonUtil:工具類

public class CommonUtil {/** * 生成32位編碼,不含橫線 * * @return uuid串 */public static String getUUID() { String uuid = UUID.randomUUID().toString().trim().replaceAll('-', ''); return uuid.toUpperCase();}/** * 得到當(dāng)前日期格式化后的字符串,格式:yyyy-MM-dd(年-月-日) * @return 當(dāng)前日期格式化后的字符串 */public static String getTodayStr(){ return new SimpleDateFormat('yyyy-MM-dd').format(new Date()) ;}/** * 將對(duì)象轉(zhuǎn)化成json * * @param t * @return * @throws JsonProcessingException */public static <T> String toJson(T t) throws JsonProcessingException { return OBJECT_MAPPER.get().writeValueAsString(t);}}

UserPojoRes:實(shí)體類

@Setter@Getter@ToStringpublic class UserPojoRes extends BaseRowModel implements Serializable { private static final long serialVersionUID = -2145503717390503506L; /** * 主鍵 */ @ExcelProperty(value = 'ID', index = 0) private String id; /** * 姓名 */ @ExcelProperty(value = '用戶名', index = 1) private String name; public UserPojoRes(String id, String name) { this.id = id; this.name = name; } public UserPojoRes(){ }}

驗(yàn)證

模板下載

這里將模板文件放在resources中

@GetMapping('/exportExcelTempalte')@ApiOperation(value = '下載導(dǎo)入模板')public void exportExcelTempalte(HttpServletResponse response) throws Exception { //Resource目錄中的文件 String filePath = '/excels/導(dǎo)入模板.xlsx'; ClassPathResource classPathResource = new ClassPathResource(filePath); Workbook workbook=WorkbookFactory.create(classPathResource.getInputStream()); ExcelUtil.downLoadExcel('導(dǎo)入模板.xlsx', response, workbook);}

Excel文件導(dǎo)入

@PostMapping('/importExcel')@ApiOperation(value = 'Excel文件導(dǎo)入')public Response importExcel(HttpServletRequest request, MultipartFile file, HttpServletResponse response) throws Exception { List<Object> objects = ExcelUtil.readMoreThan1000RowBySheetFromInputStream(file.getInputStream(),null); List<UserPojoRes> list = new ArrayList<>(); for (Object o : objects) { UserPojoRes userPojoRes = new UserPojoRes(); List<String> stringList = (List<String>) o; userPojoRes.setId(stringList.get(0) != null ? stringList.get(0).toString() : ''); userPojoRes.setName(stringList.get(1) != null ? stringList.get(0).toString() : ''); list.add(userPojoRes); } String json = CommonUtil.toJson(list); return new Response(json);}

SpringBoot中EasyExcel實(shí)現(xiàn)Excel文件的導(dǎo)入導(dǎo)出

Excel文件導(dǎo)出

@Value('${project.tmp.files.path}')public String filesPath;@GetMapping('/exportExcel')@ApiOperation(value = 'Excel文件導(dǎo)出')public void exportExcel(HttpServletResponse response) throws Exception { //創(chuàng)建臨時(shí)文件 String path = filesPath + CommonUtil.getUUID() + '.xlsx'; List<UserPojoRes> list = new ArrayList<>(); UserPojoRes userPojoRes = new UserPojoRes('009', '張三'); UserPojoRes userPojoRes1 = new UserPojoRes('009', '李四'); list.add(userPojoRes); list.add(userPojoRes1); ExcelUtil.writeWithTemplate(path, list); // 根據(jù)excel創(chuàng)建對(duì)象 Workbook workbook = WorkbookFactory.create(new FileInputStream(path)); String fileName = '用戶模塊' + CommonUtil.getTodayStr() + '.xlsx'; ExcelUtil.downLoadExcel(fileName, response, workbook);}

SpringBoot中EasyExcel實(shí)現(xiàn)Excel文件的導(dǎo)入導(dǎo)出

到此這篇關(guān)于SpringBoot中EasyExcel實(shí)現(xiàn)Excel文件的導(dǎo)入導(dǎo)出的文章就介紹到這了,更多相關(guān)Java Excel文件導(dǎo)入導(dǎo)出內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: excel
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲综合电影一区二区三区| 久久亚洲一区| 国产一区二区三区久久久久久久久| 久久久国产精品入口麻豆| 日韩精品亚洲一区二区三区免费| 99成人超碰| 日韩精品中文字幕一区二区| 蜜桃传媒麻豆第一区在线观看| 夜久久久久久| 久久精品系列| 亚洲综合图色| 精品国产乱码久久久| 久久免费国产| 蜜臀久久99精品久久久画质超高清| 美女久久99| 黑人精品一区| 日韩精品三级| 97久久精品| 福利精品一区| 精品亚洲a∨一区二区三区18| 久久午夜影视| 国产盗摄——sm在线视频| 国产精品久久免费视频| 国产免费av一区二区三区| 久久国产乱子精品免费女| 亚洲作爱视频| 欧美中文高清| 欧美综合另类| 99久久www免费| 爽爽淫人综合网网站| 国产日韩1区| 久久久久久亚洲精品美女| 你懂的亚洲视频| 欧美二区视频| 久久国产精品亚洲77777| 在线精品视频一区| 日韩欧美一区二区三区在线观看 | 五月天激情综合网| 1000部精品久久久久久久久| 九色porny丨国产首页在线| 五月激情久久| 欧美亚洲激情| 午夜电影一区| 石原莉奈在线亚洲三区| 免费黄色成人| 亚洲资源网站| 欧美激情综合| 伊人久久高清| 日韩欧美精品综合| 精品久久福利| 精品中文一区| 亚洲男人在线| 精品国产日韩欧美精品国产欧美日韩一区二区三区 | 成人精品动漫一区二区三区| 日韩av首页| 久久午夜精品| 国产精品v一区二区三区| 亚洲深夜视频| 亚洲风情在线资源| 中文精品电影| 国产伦理一区| 深夜福利视频一区二区| 男人的天堂亚洲一区| 欧美激情福利| 日韩精品一二三四| 日本中文字幕视频一区| 日本免费一区二区视频| 深夜视频一区二区| 丝袜美腿高跟呻吟高潮一区| 日韩电影免费网站| 国产精品porn| 国产一区二区三区四区五区传媒| 国产中文在线播放| 欧美激情 亚洲a∨综合| 久久丁香四色| 精品免费av| 久久精品亚洲人成影院 | 在线日韩电影| 欧美伊人影院| 久久九九精品| 亚洲午夜黄色| 性欧美xxxx免费岛国不卡电影| 97久久精品| 久久精品国产68国产精品亚洲| 亚洲综合电影| 中文在线а√天堂| 婷婷综合亚洲| 日韩一区二区三区免费| 国产精品一区二区免费福利视频| 亚洲福利一区| 日本综合精品一区| 91精品日本| 午夜在线一区二区| 国产亚洲欧美日韩精品一区二区三区 | 亚洲午夜精品久久久久久app| 天海翼精品一区二区三区| 欧美在线亚洲| 国产一区二区精品福利地址| 日本不卡在线视频| 高清av一区| 热久久久久久久| 激情黄产视频在线免费观看| 国产一区日韩一区| 日韩欧美午夜| 国产视频亚洲| 激情国产在线| 久久国产视频网| 亚洲天堂一区二区| 久久久久久一区二区| 免费久久99精品国产| 性欧美69xoxoxoxo| 久久99高清| 日韩在线观看一区二区三区| 九一国产精品| 成人在线免费观看网站| 日本а中文在线天堂| 日韩欧美久久| 欧美xxxx中国| 亚洲欧美日本国产| 精品久久中文| 欧美影院精品| 亚洲欧美视频一区二区三区| 国产精品日本| 日韩国产一区| 国产suv精品一区| 中文视频一区| 精品久久91| 极品日韩av| 日本中文字幕一区二区| 蜜桃成人av| 亚洲日本免费电影| 欧美激情综合| 亚洲激情精品| 国产一区二区三区久久| 亚洲精品无吗| 国产亚洲一区在线| 92国产精品| 精品日本视频| 欧美1区二区| 久久久精品国产**网站| 久久这里只有| 肉色欧美久久久久久久免费看| 国产亚洲电影| 久久不卡国产精品一区二区| 国产精品99久久免费观看| 精品三级国产| 99视频精品全部免费在线视频| 国内激情久久| 欧美成人基地| 国产精品97| 日韩精品一二区| 五月激激激综合网色播| 久久中文欧美| 国产一区导航| 人人爱人人干婷婷丁香亚洲| 国产一区二区三区91| 青青久久av| 亚洲精品四区| 视频小说一区二区| 视频一区视频二区中文| 国产成人免费av一区二区午夜| 99精品电影| 国产精品一级| 免费观看在线综合| 国产欧美三级| 日韩精品视频一区二区三区| 午夜精品婷婷| 国产精品黄网站| 久久香蕉网站| 日韩激情啪啪| 日韩网站在线| 国产欧美日韩视频在线| 精品中国亚洲| 性欧美xxxx免费岛国不卡电影| 亚洲精品少妇| 四虎国产精品免费观看| 久久亚洲影院| 国产suv精品一区| 蜜桃一区二区三区在线| 国产精品v亚洲精品v日韩精品| 国产精品中文字幕亚洲欧美| 国产午夜久久| 国产成人精品亚洲线观看| 视频一区欧美日韩| 久久国产免费| 激情综合自拍| 风间由美中文字幕在线看视频国产欧美| 一区二区三区国产盗摄| 在线国产一区| 亚洲精品中文字幕乱码| 婷婷成人在线| 欧美成人综合| 91久久国产| 性色一区二区| 久久成人精品| 日韩高清一区| 奇米狠狠一区二区三区| 日韩中文一区二区| 香蕉视频成人在线观看| 99pao成人国产永久免费视频|