基于POI和easyexcel实现excel文件读写-多列表加下拉选项框

article/2025/9/17 23:45:13

实现概要:公司使用excel整理微服务基线,原来老的excel模板已经不适用,所以需要将微服务从老的excel转移到新的模板中,由于微服务数量较多而且都是重复的复制粘贴的工作,所以决定使用工具完成。

具体实现:使用POI读取旧exel模板中所需要的字段信息,使用easyexcel将读取的信息填充到新的excel模板中

1、创建maven项目引入依赖,主要是POI和easyexcel,其余的为辅助工具包

<dependencies><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.14</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>2.0.3</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>2.0.3</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.19.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.2</version></dependency>
</dependencies>

2、读

旧模板如下,涉及到公司信息已将关键信息清空

实体类,用于接收读取出的字段

public class BaseServiceData {/*** 技术类型*/private String technicalType;/*** 业务类型*/private String businessType;/*** 服务所属系统*/private String serverSystem;/*** 服务英文名名称*/private String serverEnglishName;/*** 服务器中文名字*/private String serverChineseName;/*** 功能描述*/private String functionDescription;/*** 发布至ESB名称*/private String esbName;/*** 输入参数列表*/private List<InputParameter> inputParameterList;/*** 输出参数列表*/private List<OutputParameter> outputParameterList;/*** 输入参数例子*/private String inputParameterExample;/*** 输出参数例子*/private String outputParameterExample;@Datapublic static class InputParameter {/*** 参数层级*/private String inputLevel = " ";/*** 元素名称*/private String inputElementName = " ";/*** 约束*/private String inputBind = "";/*** 类型*/private String inputType = " ";/*** 描述*/private String inputDescription = " ";}@Datapublic static class OutputParameter {/*** 参数层级*/private String outputLevel = " ";/*** 元素名称*/private String outputElementName = " ";/*** 约束*/private String outputBind = "";/*** 类型*/private String outputType = " ";/*** 描述*/private String outputDescription = " ";}
}

 读取excel代码如下 

/*** 交易excel** @param inputStream 输入流* @return {@link BaseServiceData}*/public static BaseServiceData dealExcel(InputStream inputStream) {try {
//            XSSFWorkbook xssfWorkbook = new XSSFWorkbook(inputStream);HSSFWorkbook hssfWorkbook = new HSSFWorkbook(inputStream);//读第一个sheet页HSSFSheet sheetAt = hssfWorkbook.getSheetAt(0);BaseServiceData baseServiceData = new BaseServiceData();List<BaseServiceData.InputParameter> inputParameterList = new ArrayList<>();List<BaseServiceData.OutputParameter> outputParameterList = new ArrayList<>();//获取有效行数int rowsNum = sheetAt.getPhysicalNumberOfRows();//逐行读取数据for (int i = 0; i < rowsNum; i++) {log.info("读取第{}行", i);HSSFRow row = sheetAt.getRow(i);if (row == null) {continue;}HSSFCell firstCell = row.getCell(0);if (firstCell == null) {log.error("模板存在错误,第{}行第一列不能为空,跳过当前行", i);continue;}String value;//判断每一行的第一个cell元素类型switch (firstCell.getCellType()) {case STRING:if ("技术类别".equals(firstCell.getStringCellValue())) {HSSFCell cell = row.getCell(1);String cellValue = cell.getStringCellValue();cellValue = CONVERT_MAP.getOrDefault(cellValue, cellValue);baseServiceData.setTechnicalType(cellValue);baseServiceData.setBusinessType(cellValue);} else if ("服务英文名称".equals(firstCell.getStringCellValue())) {HSSFCell cell = row.getCell(1);baseServiceData.setServerEnglishName(cell.getStringCellValue());baseServiceData.setEsbName(cell.getStringCellValue());} else if ("服务中文名称".equals(firstCell.getStringCellValue())) {HSSFCell cell = row.getCell(1);baseServiceData.setServerChineseName(cell.getStringCellValue());} else if ("功能描述".equals(firstCell.getStringCellValue())) {HSSFCell cell = row.getCell(1);baseServiceData.setFunctionDescription(cell.getStringCellValue());} else if ("输入".equals(firstCell.getStringCellValue())) {for (int j = i + 1; j < rowsNum; j++) {HSSFRow sheetAtRow = sheetAt.getRow(j);if (sheetAtRow == null) {continue;}HSSFCell cell = sheetAtRow.getCell(0);if (cell.getCellType().equals(CellType.STRING) && "输出".equals(cell.getStringCellValue())) {break;}// 输入对象BaseServiceData.InputParameter inputParameter = new BaseServiceData.InputParameter();HSSFCell levelCell = sheetAtRow.getCell(1);if (levelCell == null) {inputParameter.setInputLevel("");} else {inputParameter.setInputLevel(sheetAtRow.getCell(1).getStringCellValue());}if (sheetAtRow.getCell(2) == null) {inputParameter.setInputElementName("");} else {inputParameter.setInputElementName(sheetAtRow.getCell(2).getStringCellValue());}HSSFCell cell4 = sheetAtRow.getCell(4);if (cell4 == null) {inputParameter.setInputType("");} else {String cellValue = cell4.getStringCellValue();cellValue = CONVERT_MAP.getOrDefault(cellValue, cellValue);inputParameter.setInputType(cellValue);}if (sheetAtRow.getCell(6) == null) {inputParameter.setInputDescription("");} else {inputParameter.setInputDescription(sheetAtRow.getCell(6).getStringCellValue());}inputParameterList.add(inputParameter);}baseServiceData.setInputParameterList(inputParameterList);} else if ("输出".equals(firstCell.getStringCellValue())) {for (int j = i + 1; j < rowsNum; j++) {HSSFRow sheetAtRow = sheetAt.getRow(j);if (sheetAtRow == null) {continue;}HSSFCell cell = sheetAtRow.getCell(0);if (cell.getCellType().equals(CellType.STRING) && "输入示例".equals(cell.getStringCellValue())) {break;}// 输出对象BaseServiceData.OutputParameter outputParameter = new BaseServiceData.OutputParameter();HSSFCell levelCell = sheetAtRow.getCell(1);if (levelCell == null) {outputParameter.setOutputLevel("");} else {outputParameter.setOutputLevel(sheetAtRow.getCell(1).getStringCellValue());}HSSFCell cell2 = sheetAtRow.getCell(2);if (cell2 == null) {outputParameter.setOutputElementName("");} else {outputParameter.setOutputElementName(sheetAtRow.getCell(2).getStringCellValue());}if (sheetAtRow.getCell(4) == null) {outputParameter.setOutputType("");} else {String cellValue = sheetAtRow.getCell(4).getStringCellValue();cellValue = CONVERT_MAP.getOrDefault(cellValue, cellValue);outputParameter.setOutputType(cellValue);}if (sheetAtRow.getCell(6) == null) {outputParameter.setOutputDescription("");} else {outputParameter.setOutputDescription(sheetAtRow.getCell(6).getStringCellValue());}outputParameterList.add(outputParameter);}baseServiceData.setOutputParameterList(outputParameterList);} else if ("输入示例".equals(firstCell.getStringCellValue())) {HSSFRow sheetAtRow = sheetAt.getRow(i + 1);HSSFCell sheetAtRowCell = sheetAtRow.getCell(0);baseServiceData.setInputParameterExample(sheetAtRowCell.getStringCellValue().trim());} else if ("输出示例".equals(firstCell.getStringCellValue())) {HSSFRow sheetAtRow = sheetAt.getRow(i + 1);HSSFCell sheetAtRowCell = sheetAtRow.getCell(0);baseServiceData.setOutputParameterExample(sheetAtRowCell.getStringCellValue().trim());}break;case NUMERIC:case BOOLEAN:case BLANK:default:break;}}return baseServiceData;} catch (IOException e) {log.error(e.getMessage());}return new BaseServiceData();}

3、写

新模板如下

下拉框模型对象

package com.cong.pojo;import lombok.Builder;
import lombok.Data;/*** 下拉框模型** @Author zhangyc* @Date 2022/10/17 11:10* @PackageName:com.cong.handles* @ClassName: SpinnerModel* @Description: TODO* @Version 1.0*/
@Data
public class SpinnerModel {private Integer startColumnIndex;private Integer endColumnIndex;private Integer startRowIndex;private Integer endRowIndex;/*** 下拉框选项*/private String[] spinnerData;
}

下拉框处理器

package com.cong.handles;import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.cong.pojo.SpinnerModel;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddressList;import java.util.List;/*** @Author zhangyc* @Date 2022/10/17 11:46* @PackageName:com.cong.handles* @ClassName: CustomSpinnerHandler* @Description: TODO* @Version 1.0*/
public class CustomSpinnerHandler implements SheetWriteHandler {/*** 下拉框信息列表*/private List<SpinnerModel> spinnerList;public CustomSpinnerHandler(List<SpinnerModel> spinnerList) {this.spinnerList = spinnerList;}@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {Sheet sheet = writeSheetHolder.getSheet();DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();for (SpinnerModel spinnerModel : spinnerList) {//校验开始列索引大于结束列索引,或者开始行索引大于结束行索引if (spinnerModel.getStartColumnIndex() > spinnerModel.getEndColumnIndex() || spinnerModel.getStartRowIndex() > spinnerModel.getEndRowIndex()) {continue;}DataValidationConstraint constraint = dataValidationHelper.createExplicitListConstraint(spinnerModel.getSpinnerData());//设置单元格范围CellRangeAddressList addressList = new CellRangeAddressList(spinnerModel.getStartRowIndex(), spinnerModel.getEndRowIndex(), spinnerModel.getStartColumnIndex(), spinnerModel.getEndColumnIndex());DataValidation validation = dataValidationHelper.createValidation(constraint, addressList);sheet.addValidationData(validation);}}
}

 填充模板代码

 //设置下拉框模型String[] spinnerData1 = new String[]{"string", "number", "integer", "object", "array", "boolean"};String[] spinnerData2 = new String[]{"string", "number", "integer", "object", "array", "boolean"};SpinnerModel spinnerModel1 = new SpinnerModel();spinnerModel1.setSpinnerData(spinnerData1);spinnerModel1.setStartRowIndex(35);spinnerModel1.setEndRowIndex(35 + inputParameterList.size()-1);spinnerModel1.setStartColumnIndex(3);spinnerModel1.setEndColumnIndex(3);SpinnerModel spinnerModel2 = new SpinnerModel();spinnerModel2.setSpinnerData(spinnerData2);spinnerModel2.setStartRowIndex(35 + inputParameterList.size() + 1);spinnerModel2.setEndRowIndex(35 + inputParameterList.size() + 1 + outputParameterList.size()-1);spinnerModel2.setStartColumnIndex(3);spinnerModel2.setEndColumnIndex(3);List<SpinnerModel> spinnerList = new ArrayList<>();spinnerList.add(spinnerModel1);spinnerList.add(spinnerModel2);//写入模板excelWriter = EasyExcel.write(newPath).excelType(ExcelTypeEnum.XLS).withTemplate(templatePath).registerWriteHandler(new CustomSpinnerHandler(spinnerList)).build();WriteSheet writeSheet = EasyExcel.writerSheet().build();//每写一行自动添加一行新空行FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();//写列表excelWriter.fill(new FillWrapper("a", inputParameterList), fillConfig, writeSheet);excelWriter.fill(new FillWrapper("b", outputParameterList), fillConfig, writeSheet);//写其他信息excelWriter.fill(baseServiceData, fillConfig, writeSheet);excelWriter.close();

需要注意的是如果模板中存在多个列表,需要加前缀区分

如果新模板中有下拉选项填充,则需要去掉告警的勾选

 以上仅作为个人工作学习记录,如有不妥敬请指正。


http://chatgpt.dhexx.cn/article/H8fM57c9.shtml

相关文章

EXCEL如何设置下拉选项打勾 + 不正常选项拉红

Excel怎么制作能打勾叉的下拉菜单_360新知 (so.com) 首先&#xff0c;选中要设置的单元格&#xff0c;然后&#xff0c; 开始→条件格式→突出显示单元格规则→等于

Java - EasyExcel结合VBA实现Excel导出下拉多选框与单选框

需求&#xff1a;导出一个带有单选下拉框与多选下拉框的excel模板 思路&#xff1a;1.使用VBA脚本设置带有多选框的模板2.使用EasyExcel给字段填充单选下拉框数据源一、创建带有多选框宏的excel模板 *.xls&#xff1a;不管有没有宏程序的话都是xls文件 *.xlsx文件&#xff1…

Java Excel POI添加多选下拉框

给自己打个广告&#xff0c;最近弄了个Excel的工具&#xff0c;支持下拉框&#xff0c;级联下拉框&#xff0c;隐藏Sheet&#xff0c;多线程大数据量导出&#xff0c;生产者消费者模式读取&#xff0c;代码大部分都有注释&#xff0c;有兴趣的朋友可以看看&#xff0c;觉得不错…

php excel复选框,excel如何实现下拉框复选

excel如何实现下拉框复选? EXCEL选择下拉框实现复选 第一步:新建一个excel且设置数据有效性【选中X列--数据--有效性】 第二步:开发工具--查看代码--把代码复制进去保存就OK了 代码如下:Private Sub Worksheet_Change(ByVal Target As Range) Developed by Contextures In…

使用VBA实现Excel下拉多选

Excel的下拉多选 新项目需要excel导入时的下拉多选框 Excel表格下拉单选很简单&#xff0c;先给表格做成单选。参照 [excel怎么设置下拉选择项] (https://jingyan.baidu.com/article/1876c85255d929890a13767d.html) Excel要想做成多选首先需要启用宏&#xff0c;如果Excel中…

Excel VB脚本,下拉框多选

1.数据-数据验证&#xff0c;先做出单选效果 在弹出的数据验证窗口选择 序列&#xff0c;然后选择下拉的数据来源 2.开发者工具-VisualBasic 在打开的窗口里面&#xff0c;选择需要下拉的sheet页&#xff0c;然后双击sheet,打开VB的脚本窗口 在窗口输入一下。 3.开发者工具…

office中excel设置下拉框多选

我参照了这篇文章 https://www.php.cn/topic/excel/444717.html 这篇文章整体写得不错&#xff0c;但是有些小瑕疵 问题1&#xff1a;在模块1中保存。 这里并没有说清楚 具体是&#xff1a;VBA编辑器中--插入---模块 然后复制以下代码 Public ReLoad As Boolean 开关listb…

Excel怎么下拉框多选

打开Exlce&#xff0c; 确定&#xff0c;然后 右击查看代码&#xff0c;把这段代码复制到新建的文件里面 此时Excel会给出提示&#xff0c;选择否&#xff0c;&#xff0c;系统会提示保存&#xff0c;在保存的时候选择启用宏的工作簿然后保存&#xff0c;此时Excel下拉框多选就…

关于EXCLE 下拉框多选的设置

关于EXCLE 下拉框多选的设置。 本文转载于&#xff1a;https://www.cnblogs.com/boosasliulin/p/5970120.html 本文转载于&#xff1a;https://blog.csdn.net/qq_33269520/article/details/81173811 打开Exlce&#xff0c;设置数据有效性 确定&#xff0c;然后 右击查看代码…

php下拉多选框,excel下拉框多选打勾的设置方法

excel下拉框多选打勾的设置方法 一、显示“开发工具”选项卡。打开Excel2010,点击左上方“文件”图标。点击“选项”,弹出“Excel选项”对话框,在“自定义功能区”中勾选“开发工具”,点击确定。 二、设置下拉列表的选项内容。将工作表sheet2名称修改为“data”,并在A列输入…

Excel 设置下拉框多选

问题描述 Excel的下拉框无法多选 解决办法 为Excel文件添加VB代码&#xff0c;文件后缀需由.xlsx变为.xlsm&#xff0c;否则仍无法实现该功能 操作步骤 ① 选中当前Sheet ② 右键选择查看代码 ③ 将代码复制进去 ④ 再将文件保存为.xlsm格式的即可 附代码如下 Option Exp…

Excel下拉框多选(支持再次选择已选项会取消选择)

比如我做一个表格&#xff0c;其中一项是“部门类型”&#xff0c;这一项中&#xff0c;选项有&#xff1a;财务部&#xff0c;人事部&#xff0c;开发部&#xff0c;销售部 用户在选择的时候&#xff0c;可以选择&#xff1a;人事部&#xff0c;开发部 那么在“部门类型”这个…

Excel下拉框设置多选

Excel下拉框一般只能单选&#xff0c;但有时候需要多选&#xff0c;多选的方法如下&#xff1a; 以office 2016中的excel为例&#xff1a; 1、数据验证入口 2、设置数据 3、sheet页右击查看代码 4、复制下面代码进去&#xff1a; 5、效果如下&#xff1a; VB代码如下&#xf…

【已解决】如何做excel表的下拉框多选

最近因为项目需求&#xff0c;要制作一个excel导入的模板&#xff0c;模板中要求某几列的下拉框是多选的。。不得不临时研究了一下vba。其间各种心酸不多说。。。。。。 首先&#xff0c;这个是需要启用宏&#xff0c;在vb编辑器里写代码&#xff0c;所以你要确保你的excel是可…

Excel表格实现下拉复选框多选

Excel表格实现下拉复选框多选 文章目录 1准备数据源2开启“开发工具”3具体实现3.1插入列表框控件3.2设置列表框控件属性3.3编辑VBA代码实现功能3.4调试运行 1准备数据源 打开要实现的excel表格&#xff0c;将选项数据放到sheet2 2开启“开发工具” 开启“开发工具”步骤&…

【C语言】用循环语句输出菱形

//用循环语句输出菱形 #include <stdio.h> int main() {int i,j;for(i0;i<3;i) //上4行{for(j0;j<3;j) //上4行的左边{if(ij<2)printf(" ");elseprintf("*");}for(j4;j<6;j) //上4行的右边{if(j-i>4)printf(" ");…

用c语言输出一个菱形

这是一道课后题作业&#xff0c;针对菱形的空格我使用了" "的输出方式&#xff0c;应该还有更好的方法&#xff1f;是不是还有格式化字符能直接居中对正&#xff1f;待思考。 代码如下&#xff1a; #include<stdio.h>int main(){int i, j, k, a;printf("…

C语言输出菱形不是梦

如果对其他经典算法感兴趣&#xff0c;可以点击我的主页&#xff0c;有惊喜哟 给大家看看咱的诚意&#xff1a; 先来个流程图&#xff08;虽然只写了一半&#xff0c;但是下面的一半比猫画虎就行&#xff09; 废话不多说上代码&#xff08;欢迎交流哟&#xff09;&#xff1a…

[C语言]——利用循环输出菱形

题目要求如下&#xff1a; 用C语言输出以下图形&#xff1a;*************************************************************************************总体思路&#xff1a; 将菱形拆分开&#xff0c;一行一行看。 前七行是由递减的空格和递增符号组成&#xff0c; 后六行是由…

【C语言】输出“*”菱形图案

问题&#xff1a;在屏幕上输出一个菱形图案   目标图案&#xff1a;      实现思路&#xff1a;   由目标图案可知&#xff1a;该图案共有13行&#xff0c;每行除了有“&#xff0a;”外&#xff0c;第一个“&#xff0a;”之前还包括空格。我们可以把整个图案分为…