easyExcel读数据后在写入另一个excel

2024-01-03 15:58

本文主要是介绍easyExcel读数据后在写入另一个excel,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

需求说明:如下图所示,excel中有4个sheet,每个sheet的数据格式都一样,有5列,第一列为订单id,现在要根据订单id到数据库中查询出其他几列的信息并补充到excel中。

代码如下:首先为service中的主方法

 public void userMessage() {
//        String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();ApplicationHome h = new ApplicationHome(getClass());File jarF = h.getSource();String path = jarF.getParentFile().toString();log.info("excel service jar2 path is:"+path+"==============================");//获取附件1的excelString adjunctOnePath = path+ File.separator+"1.xlsx";String adjunctOneWritePath = path+ File.separator+"1_complete.xlsx";File srcFile = new File(adjunctOnePath);File destFile = new File(adjunctOneWritePath);FileUtils.copyFile(srcFile,destFile);ExcelReader excelReader = EasyExcel.read(adjunctOnePath).excelType(ExcelTypeEnum.XLSX).autoCloseStream(true).build();// 新建一个ExcelWriterBuilder实例ExcelWriter excelWriter = EasyExcel.write(new FileOutputStream(destFile)).excelType(ExcelTypeEnum.XLSX).autoCloseStream(true).build();processSheet(0,excelReader,excelWriter,this::completeSheet1Data);processSheet(1,excelReader,excelWriter,this::completeSheet2Data);processSheet(2,excelReader,excelWriter,this::completeSheet2Data);processSheet(3,excelReader,excelWriter,this::completeSheet4Data);excelReader.finish();excelWriter.finish();}

上面首先我获取到了jar包的所在目录,因为我把excel和jar包放到了同一目录,其中1.xlsx是原始文件,1_complete.xlsx是要写入数据的文件,我这里直接复制了一份原文件。

然后我分别创建了ExcelReader 和ExcelWriter俩个对象,用于读和写excel。后面就是处理4个sheet的代码,我调用了4次方法,下面看下主要逻辑processSheet的代码:

private void processSheet(int sheetNo,ExcelReader excelReader, ExcelWriter excelWriter, Consumer<Map<Integer, String>> consumer) {Map<Integer, String> head = new HashMap<>();List<List<String>> data = new LinkedList<>();// 构建输出的sheetWriteSheet writeSheet = EasyExcel.writerSheet(sheetNo,"模板-"+sheetNo).build();final int[] num = {0};ReadSheet readSheet = EasyExcel.readSheet(sheetNo).registerReadListener(new AnalysisEventListener<Map<Integer, String>>() {@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {head.putAll(headMap);List<List<String>> header = head.values().stream().map(Collections::singletonList).collect(Collectors.toList());writeSheet.setHead(header);}@Overridepublic void invoke(Map<Integer, String> row, AnalysisContext analysisContext) {num[0]++;//补充数据consumer.accept(row);data.add( row.values().stream().collect(Collectors.toList()));if(num[0]%50==0){log.info("================read num is {}==============",num[0]);excelWriter.write(data,writeSheet);data.clear();}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// 这里可以打印日志告知所有行读取完毕System.out.println("读取完毕");excelWriter.write(data,writeSheet);}}).build();writeSheet.setSheetName(readSheet.getSheetName());excelReader.read(readSheet);}

可以看到有4个参数,分别是sheet的序号(从0开始),还有上面提到的ExcelReader 和ExcelWriter俩个对象,最后是一个Consumer对象主要用来根据orderid查询其他列的数据,这个consumer跟我的业务有关,不是重点。上面可以看到构造readSheet 对象的时候注册了一个AnalysisEventListener,这个对象内部有三个方法:

invokeHeadMap方法会读取到excel的标题行,我这里读取到之后直接设置到了writeSheet里。

invoke方法会没每一行数据都会触发一次,我这里对每一行数据调用了上面提到的Consumer进行了处理(主要是到数据库里查询其他的数据),将处理后的数据放到一个list里保存,同时每50条会写一次,防止内存数据过多。

doAfterAllAnalysed方法 读取完之后会触发,我这里接着把剩余的数据写入到writesheet。

下面是Consumer对象对应的方法,如下:主要是查询数据。

 private void completeSheet2Data(Map<Integer, String> row) {String outerId = row.get(0);Condition condition = new Condition(BaixinCreditApply.class);condition.createCriteria().andEqualTo("outerOrderId",outerId);BaixinCreditApply   baixinCreditApply = baixinCreditApplyMapper.selectOneByExample(condition);if(Objects.isNull(baixinCreditApply)){log.info("======根据outer id {} 未查询到数据========",outerId);return ;}Long uid = baixinCreditApply.getUid();//查询身份证号String idCard = "-";String idStartDate = "-";String idEndDate = "-";condition = new Condition(OcrIdCard.class);condition.createCriteria().andEqualTo("uid",uid);OcrIdCard ocrIdCard = ocrIdCardMapper.selectOneByExample(condition);if(Objects.nonNull(ocrIdCard)){String idNumberAes = ocrIdCard.getIdNumberAes();idCard = BasicInfoEncryptUtil.decrypt(idNumberAes);String validDate = ocrIdCard.getValidDate();if(StringUtils.isNotBlank(validDate)&&validDate.indexOf("-")>=0){idStartDate = validDate.split("-")[0];idEndDate = validDate.split("-")[1];}}row.put(1,String.valueOf(uid));row.put(2,idStartDate);row.put(3,idEndDate);row.put(4,idCard);}

 

 

 

 

这篇关于easyExcel读数据后在写入另一个excel的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/566250

相关文章

Mac excel 同时冻结首行和首列

1. 选择B2窗格 2. 选择视图 3. 选择冻结窗格 最后首行和首列的分割线加粗了就表示成功了

LeetCode--171 Excel表列序号

题目 给定一个Excel表格中的列名称,返回其相应的列序号。例如,A -> 1B -> 2C -> 3...Z -> 26AA -> 27AB -> 28 ... 示例 示例 1:输入: "A"输出: 1示例 2:输入: "AB"输出: 28示例 3:输入: "ZY"输出: 701 class Solution {public:int titleToNumber(strin

浅谈 MySQL for excel

欢迎关注微信公众号“Python生态智联”  MySQL for excel是一个大小只有几兆的MySQL附件,它能让我们在Microsoft excel中处理MySQL数据。小编用了两天时间浏览了MySQL for excel的使用指南并按demo演示了一遍(手册地址https://dev.mysql.com/doc/mysql-for-excel/en/),现从功能和局限两方面对MySQL

Excel实用技巧——二级下拉菜单、数据验证

EXCEL系列文章目录   Excel系列文章是本人亲身经历职场之后萌发的想法,为什么Excel覆盖如此之广,几乎每个公司、学校、家庭都在使用,但是它深藏的宝藏功能却很少被人使用,PQ、BI这些功能同样适用于数据分析;并且在一些需要简单及时的数据分析项目前,Excel是完胜python、R、SPSS这些科学专业的软件的。因此决心开启Excel篇章。 数据分析为什么要学Excel Excel图表

PHP生成csv格式Excel,秒级别实现excel导出功能

防止报超内存,兼容中文,兼容科学技术法。 爽。。。。很爽。。。。 /*** 告诉浏览器下载csv文件* @param string $filename*/public static function downloadCsv($data, $filename, $encoding = 'utf-8'){header("Content-type: text/csv");header("Conten

PHP 读取或生成大的Excel

场景,在很多情况下,需要读取Excel文件。 常用的有PHPExcel包或者使用 maatwebsite/excel 包 但是使用这个包读取或生成excel,如果excel文件过大,很容易出现超内存情况。 解决方法: 上传:要求上传者使用.csv 文件上传。然后使用php自带的 fgetcsv()函数来读取文件。http://php.net/manual/zh/function.fgetc

示例:推荐一个基于第三方开源控件库DataGridFilter封装的FilterColumnDataGrid,可以像Excel拥有列头筛选器

一、目的:基于第三方开源控件库DataGridFilter封装的FilterColumnDataGrid,可以像Excel拥有列头筛选器,感兴趣的可以去下方链接地址查看开源控件库地址。本控件封装的目的在于将第三方库的皮肤和样式封装到皮肤库中可统一设置样式,同时生成nuget方便调用 二、效果如下 三、环境 VS2022 Net7 四、使用方式 1、安装nuget包:H.Con

在Qt5中创建、读取和写入JSON文件的完整指南

Qt5 提供了一个非常方便的JSON解析器,使得在C++中处理JSON数据变得非常简单。本文将详细介绍如何在Qt5中创建、读取和写入JSON文件。 读取JSON文件的示例 假设我们有一个名为test.json的JSON文件,内容如下: {"appDesc": {"description": "SomeDescription","message": "SomeMessage"},"appNam

yii2 自定义写入日志

/*** log* $message 消息* $reference array 数组*/public static function log($message, $reference = []){$message = count($reference) ? $message.PHP_EOL.print_r($reference, true) : $message;if (YII_DEBUG)

poi生成的excel,输入数字后变成1.11111111111111E+23

poi版本4.1.2 生成excel后,单元格输入数字,过长的话变成这样 解决:生成的时候设置单元格格式为文本格式 import org.apache.poi.ss.usermodel.*;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileOutputStream;import java.io.IOEx