`
whoosh
  • 浏览: 237259 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

“Java+POI+模板”三:从Excel读入一个对象列表

 
阅读更多

请先阅读 “Java+POI+模板”一:打造复杂Excel 报表  

“Java+POI+模板”二:基于对象列表输出到excel(利用反射)

我们会处理如下图所示的两个Excel,将之转化为我们的对象。



 


 

第一张图对应的对象类如下:

public class User {

	private int id;
	private String username;
	private String nickname;
	private int age;
	
	@ExcelResources(title="用户标识",order=1)
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	
	@ExcelResources(title="用户名",order=2)
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	@ExcelResources(title="用户昵称",order=3)
	public String getNickname() {
		return nickname;
	}
	public void setNickname(String nickname) {
		this.nickname = nickname;
	}
	@ExcelResources(title="用户年龄",order=4)
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public User(int id, String username, String nickname, int age) {
		super();
		this.id = id;
		this.username = username;
		this.nickname = nickname;
		this.age = age;
	}
	public User() {
		super();
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", nickname="
				+ nickname + ", age=" + age + "]";
	}
}

 第二张图对应的对象类如下:

public class Student {
	private int id;
	private String name;
	private String no;
	private String sex;
	
	@ExcelResources(title="学生标识",order=1)
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	
	@ExcelResources(title="学生姓名")
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@ExcelResources(title="学生学号", order=2)
	public String getNo() {
		return no;
	}
	public void setNo(String no) {
		this.no = no;
	}
	@ExcelResources(title="学生性别")
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Student(int id, String name, String no, String sex) {
		super();
		this.id = id;
		this.name = name;
		this.no = no;
		this.sex = sex;
	}
	
	
	public Student() {
		super();
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", no=" + no + ", sex="
				+ sex + "]";
	}
}

处理上述的Excel我们需要知道其文件路径,读取Excel的开始行和结束行,所以我们的代码如下。具体的操作我们交给handleExcel2Objs方法来处理。

/**
	 * 从文件路径读取相应的Excel文件到对象列表
	 * @param path 文件路径下的path
	 * @param clz 对象类型
	 * @param readLine 开始行,注意是标题所在行
	 * @param tailLine 底部有多少行,在读入对象时,会减去这些行
	 * @return
	 */
	public List<Object> readExcel2ObjsByPath(String path,Class clz,int readLine,int tailLine) {
		Workbook wb = null;
		try {
			wb = WorkbookFactory.create(new File(path));
			return handleExcel2Objs(wb, clz, readLine,tailLine);
		} catch (InvalidFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

 handleExcel2Objs方法首先会调用getHeaderMap方法,将Model类ExcelResources注解的Title与单元格的Title做匹配。然后将单元格的列号作为key,Model的get方法名改为set方法名,作为字符串设为value。返回一个Map。

/**
	 * 将Model类ExcelResources注解的Title与单元格的Title做匹配
	 * 将单元格的列号作为key,Model的get方法名改为set方法名,作为字符串设为value
	 */
	private Map<Integer,String> getHeaderMap(Row titleRow, Class clz){
		List<ExcelHeader> headers=getHeaderList(clz);
		Map<Integer,String> maps=new HashMap<Integer,String>();
		for (Cell c : titleRow) {
			String title=c.getStringCellValue();
			for (ExcelHeader eh : headers) {
				if(eh.getTitle().equals(title)){
					maps.put(c.getColumnIndex(), eh.getMethodName().replace("get", "set"));
					break;
				}
			}
		}
		return maps;
	}

 

getHeaderMap方法又会调用getHeaderList方法来返回返回Model类里面所有带有ExcelResources注解的get方法的注解信息。

/**
	 * 将Model类ExcelResources注解的Title与单元格的Title做匹配
	 * 将单元格的列号作为key,Model的get方法名改为set方法名,作为字符串设为value
	 */
	private Map<Integer,String> getHeaderMap(Row titleRow, Class clz){
		List<ExcelHeader> headers=getHeaderList(clz);
		Map<Integer,String> maps=new HashMap<Integer,String>();
		for (Cell c : titleRow) {
			String title=c.getStringCellValue();
			for (ExcelHeader eh : headers) {
				if(eh.getTitle().equals(title)){
					maps.put(c.getColumnIndex(), eh.getMethodName().replace("get", "set"));
					break;
				}
			}
		}
		return maps;
	}

 有了上述方法,handleExcel2Objs方法便可轻松将Excel转换为参数中的clz对象

/**
	 * 将Excel转换为参数中的clz对象
	 * @param wb 我们所要处理的Workbook
	 * @param clz 对象类型
	 * @param readLine 开始行,注意是标题所在行
	 * @param tailLine 底部有多少行,在读入对象时,会减去这些行
	 * @return
	 */
	private List<Object> handleExcel2Objs(Workbook wb,Class clz,int readLine,int tailLine) {
		Sheet sheet=wb.getSheetAt(0);
		List<Object> objs=null;
		try {
			Row row=sheet.getRow(readLine);
			objs = new ArrayList<Object>();
			Map<Integer,String> maps =getHeaderMap(row, clz);
			if(maps==null||maps.size()<=0) throw new RuntimeException("要读取的Excel的格式不正确,检查是否设定了合适的行");
			Object obj=null;
			for(int i=readLine+1;i<=sheet.getLastRowNum()-tailLine;i++){
				row=sheet.getRow(i);
				obj=clz.newInstance();
				for (Cell c : row) {
					int ci = c.getColumnIndex();
					String mn=maps.get(ci).substring(3);
					mn=mn.substring(0, 1).toLowerCase()+mn.substring(1);
					BeanUtils.copyProperty(obj, mn,this.getCellValue(c));
				}
				objs.add(obj);
			}
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return objs;
	}

 这样我们的代码就写好了,下面是测试代码。

针对于第一张图,我们第0行和最后两行是不需要的,所以传入的readLine是1,tailLine是2

针对第二张图,我们就是从0行开始读,底部也没有多余的行,所以readLine和tailLine都是0

@Test
	public void testRead01(){
		List<Object> us=ExcelUtil.getInstance().readExcel2ObjsByPath("d:/test/poi/tus.xls", User.class,1,2);
		for(Object obj:us){
			User user=(User)obj;
			System.out.println(user);
		}
	}
	@Test
	public void testRead02(){
		List<Object> stus=ExcelUtil.getInstance().readExcel2ObjsByPath("d:/test/poi/ss1.xls", Student.class,0,0);
		for(Object obj:stus){
			Student stu=(Student)obj;
			System.out.println(stu);
		}
	}

 输出的值如下:

testRead01:
User [id=1, username=aaa, nickname=水水水, age=11]
User [id=2, username=sdf, nickname=水水水, age=11]
User [id=3, username=sdfde, nickname=水水水, age=11]
User [id=4, username=aaa, nickname=水水水, age=11]
User [id=54, username=aaa, nickname=水水水, age=11]
User [id=16, username=aaa, nickname=水水水, age=11]

testRead02
Student [id=1, name=张三, no=1123123, sex=男]
Student [id=2, name=张三, no=1123123, sex=男]
Student [id=3, name=张三, no=1123123, sex=男]
Student [id=4, name=张三, no=1123123, sex=男]

 

 

  • 大小: 39 KB
  • 大小: 106 KB
分享到:
评论

相关推荐

    Apache poi 根据word模板生成word报表 替换 循环列表 图片

    Apache POI是一个强大的Java库,专门用于处理Microsoft Office格式的文件,如Word、Excel和PowerPoint。在本项目中,我们将关注如何使用Apache POI来根据预设的Word模板生成包含替换内容、循环列表和图片的动态Word...

    java 导出excel,带图片的Excel导出

    在Java编程中,导出Excel是一项常见的任务,特别是在数据分析、报表生成或数据交换等领域。而带图片的Excel导出则增加了复杂性,因为涉及到二进制数据的处理和Excel特定格式的支持。以下是一些关于如何在Java中实现...

    JAVA将数据按指定格式导出为EXCEL和从EXCEL读相关的内容视频教程.rar

    大家好,我是陈亮,JAVA将数据按指定格式导出为EXCEL和从EXCEL读相关的内容视频教程 1,把poi-2.5.1-final-20040804.jar复制到jdk的classpath下,我这里用的插件是POI 我已打好在包中。。 &lt;br&gt;我这里JDK装到...

    .NET 5 Execl导入 文件上传,下载Demo!

    NPOI是.NET版本的Apache POI,后者是Java平台上的一个库,用于处理Microsoft Office格式的文件。 - **CoreNPOI的使用**:首先,需要安装`CoreNPOI` NuGet包。接着,可以使用`HSSFWorkbook`(对于旧版的.xls文件)...

    人类预期寿命数据(世界各国)1960-2022年.xlsx

    介绍 人类预期寿命是指在特定年龄出生的人群,按照当前的死亡率水平,预期平均能够存活的年数。预期寿命衡量一个国家和地区卫生健康状况、社会经济发展水平和生活条件的重要参数 数据来源为世界银行、第四-七次全国人口普查数据 ## 一、人类预期寿命趋势 2022年,全球人类预期平均寿命为72岁。其中女性为74.5岁,男性为69.6岁 世界银行的数据显示,1960-2022年期间,人类预期寿命整体呈上升趋势。随着医疗技术的进步、公共卫生的改善、营养条件的提升以及生活方式的改变,这62年间,人类平均预期寿命提升了21岁。受到新冠疫情的影响,2021年,预期寿命有所下降,但在2022年有所回升

    光伏超级电容与蓄电池混合储能系统能量管理仿真:模型、算法及应用场景

    内容概要:本文深入探讨了光伏超级电容与蓄电池混合储能系统在能量管理方面的仿真研究。主要内容涵盖光伏Boost模块的最大功率点跟踪(MPPT)算法实现、蓄电池与超级电容的分工及其控制策略、仿真工况的设计与分析。文中不仅提供了详细的数学模型和控制算法,还展示了具体的仿真案例,如200Hz投切负载和光照突降测试,验证了系统的动态响应能力和稳定性。此外,文章强调了仿真过程中需要注意的关键技术和参数设置,为实际应用提供了宝贵的理论支持和技术指导。 适合人群:从事新能源技术研发的专业人士、高校师生及相关领域的研究人员。 使用场景及目标:适用于光伏储能系统的研究与开发,旨在提高系统的能量利用效率和稳定性,特别是在面对复杂工况时的表现。通过仿真研究,可以优化系统设计,降低成本,提升性能。 其他说明:文中提供的代码片段和仿真模型仅供参考,在实际应用中需要结合具体情况进行调整和完善。同时,建议参考更多相关领域的权威文献,以确保研究成果的科学性和可靠性。

    基于FPGA与Verilog的多波形实时可调DDS信号发生器设计

    内容概要:本文详细介绍了利用FPGA和Verilog实现的一个能够实时切换六种波形并进行频率调节的DDS信号发生器的设计。文中首先阐述了波形切换机制,通过ROM查表法实现不同波形的数据存储与读取;接着讲解了按键交互设计,确保用户可以通过三个按键轻松地控制设备的功能;然后讨论了频率调节方法,采用相位累加器实现精确的频率控制;此外,还探讨了ASK和FSK调制的具体实现方式以及一些优化技巧如PWM替代DAC等。最终经过测试验证,该发生器可以在1kHz到10MHz范围内平稳运行,具有良好的性能表现。 适合人群:对FPGA开发有一定了解的技术爱好者、电子工程专业学生或者从事相关领域的工程师。 使用场景及目标:适用于需要生成多种标准波形并且可以灵活调整输出频率的应用场合,例如实验室环境下的教学演示、科研实验或是产品原型开发阶段。 其他说明:文中提供了大量具体的Verilog代码片段作为参考,帮助读者更好地理解和复现整个项目。同时提到了一些常见问题及其解决方案,有助于初学者避开潜在陷阱。

    ABAQUS有限元软件中刀盘切削竹材模型的构建与应用

    内容概要:本文详细介绍了使用 ABAQUS 有限元软件构建刀盘切削竹材模型的方法。首先,设定了刀具的工作参数,如转速和进给速度。接着,通过创建部件、定义材料属性、装配部件、设置分析步和划分网格等步骤完成了整个模型的建立。文中还强调了材料定义的关键性,特别是竹材作为复合材料层时使用的 Hashin 准则。此外,讨论了刀具运动的设置方法,包括旋转和平移动态的组合。对于接触设置部分,则探讨了摩擦系数和损伤耦合的影响。最后,提供了模型验证的一些技巧,确保仿真结果的有效性和准确性。 适合人群:从事机械工程、材料科学及相关领域的研究人员和技术人员,尤其是对有限元分析有一定基础的人群。 使用场景及目标:适用于需要研究刀具切削竹材过程的工程项目,旨在帮助工程师们更好地理解和优化切削工艺,提高生产效率和产品质量。 其他说明:文章不仅涵盖了理论知识,还包括了大量的代码片段和实践经验,有助于读者快速掌握相关技能并在实际工作中加以运用。

    光电探测器仿真:温度特性仿真.zip

    光电材料仿真,电子仿真等;从入门到精通教程;含代码案例解析。

    Python计算机课程设计项目:基于改进UNet和GAN的图像修复系统

    基于生成对抗网络(GAN)的图像修复算法,旨在通过利用深度学习技术修复图像中的缺陷和损坏区域。算法中包括两个主要组件:一个生成器(Generator)和一个判别器(Discriminator)。生成器使用的是无注意力机制的全卷积架构UNet,而判别器采用的是PatchGAN架构。预处理过程中,加载图像和掩码文件并调整大小,进行随机掩码应用,准备模型输入。生成器根据对抗损失、感知损失和结构一致性损失调整其参数,以改善生成图像的质量和真实性。判别器评估两类图像:真实的未损坏图像和生成器产生的修复图像。通过设计生成器和判别器,算法能够有效地处理和修复图像中的缺陷。

    基于PLC1200与Factory IO的虚拟工厂仿真设计及调试经验分享

    内容概要:本文详细介绍了利用西门子TIA Portal V15.1和Factory IO构建虚拟工厂仿真的全过程。首先讲述了环境搭建,包括选择合适的PLC型号(如S7-1200)、正确配置通信参数(如IP地址)以及启用必要的通信权限。接着深入探讨了Factory IO场景的创建,强调了合理的信号映射和物理属性设置对于仿真效果的影响。随后展示了PLC程序的设计思路,特别是状态机的应用和关键逻辑的实现方法。文中还记录了一些常见的调试问题及其解决方案,例如因变量映射错误导致的传送带异常加速现象。最后分享了作者在联机调试过程中积累的经验教训,如使用Ping命令检查网络连通性和调整定时器参数避免误触发等。 适合人群:从事工业自动化领域的工程师和技术爱好者,尤其是对PLC编程和虚拟仿真感兴趣的初学者。 使用场景及目标:帮助读者掌握如何使用TIA Portal和Factory IO进行虚拟工厂仿真系统的搭建与调试,提高编程技能并减少实际项目中的试错成本。 其他说明:文中提供了大量实用的技术细节和实战案例,有助于加深理解和应用。同时提醒读者注意一些容易忽视的小问题,如IP地址配置、变量映射等,这些都是确保系统稳定运行的关键因素。

    Comsol金属贴片建模与多极子展开分析:电磁学领域的透反射计算及应用

    内容概要:本文详细介绍了如何使用Comsol进行金属贴片建模及其多极子展开分析,特别关注于透反射计算。首先,文章讲解了金属贴片建模的具体步骤,包括选择合适的物理场、绘制几何图形、设定材料属性等。接着,探讨了多极子展开的基础理论及其在Comsol中的实现方式,解释了多极子如电偶极子和磁偶极子如何影响电磁波的散射行为。随后,讨论了透反射计算的方法,强调了边界条件和求解器设置的重要性,并展示了如何通过多极子分解来分析透反射系数的变化。最后,文章还分享了一些实用技巧,如参数化扫描、网格优化和多极子分解的实际操作方法。 适合人群:从事电磁学研究的专业人士、研究生及以上学历的研究人员、对电磁仿真感兴趣的工程师。 使用场景及目标:适用于科研项目中涉及金属贴片结构的设计与分析,帮助研究人员更好地理解和预测金属贴片在不同电磁环境下的表现,尤其是透反射特性和多极子效应的应用。 其他说明:文中提供了详细的建模步骤和代码片段,便于读者动手实践并加深理解。同时,针对可能出现的问题给出了具体的解决方案,确保仿真的准确性。

    郑予彬-生成式AI提升开发者效能.pdf

    郑予彬-生成式AI提升开发者效能.pdf

    基于MATLAB的三自由度车辆动力学模型与CKF算法的质心侧偏角估计及联合仿真

    内容概要:本文详细介绍了基于MATLAB的三自由度车辆动力学模型以及利用容积卡尔曼滤波(CKF)进行车辆质心侧偏角估计的方法。首先,文章解释了三自由度模型的基本原理,包括状态方程的构建和线性轮胎模型的应用。接着,深入探讨了CKF算法的具体实现,包括容积点生成、预测和更新步骤,并展示了其相对于扩展卡尔曼滤波(EKF)的优势。此外,文章还讨论了与CarSim软件的联合仿真过程中遇到的问题及解决方案,如时钟同步和参数调试技巧。最终,通过实验验证了CKF在车辆状态估计中的高效性和准确性。 适合人群:从事车辆动力学研究、自动驾驶技术研发的专业人士,尤其是有一定MATLAB编程基础的研究人员和技术人员。 使用场景及目标:适用于需要精确估计车辆状态(如质心侧偏角、横摆角速度等)的场合,旨在提高自动驾驶系统的感知能力和控制精度。目标是帮助研究人员更好地理解和应用CKF算法,优化车辆控制系统的设计。 其他说明:文中提供了详细的代码片段和调试经验分享,有助于读者快速上手并解决实际问题。同时,强调了在特定工况下(如低附着力路面)采用自适应CKF的重要性。

    轴承故障诊断中的一维CNN与MMD-Coral迁移学习方法及其应用

    内容概要:本文详细介绍了使用一维CNN结合MMD(最大均值差异)和Coral(协方差对齐)进行轴承故障诊断的迁移学习方法。主要内容涵盖数据预处理、网络模型设计、域适应技术以及训练技巧等方面。文中使用西储大学CWRU数据集进行实验,通过滑动窗口切片、归一化等手段处理振动信号,并构建了一维CNN模型,利用MMD和Coral实现源域和目标域的特征对齐。最终模型取得了99%的准确率,验证了方法的有效性。 适合人群:对机器学习特别是迁移学习感兴趣的初学者和技术爱好者。 使用场景及目标:适用于需要解决不同工况下轴承故障诊断问题的研究人员和工程师。主要目标是通过迁移学习提高模型在新环境下的泛化能力。 其他说明:文章不仅提供了详细的理论解释,还包括具体的代码实现和可视化工具的应用,如损失曲线图、准确率曲线图、混淆矩阵和t-SNE图等,有助于读者更好地理解和评估模型性能。此外,作者还分享了一些实用的经验和技巧,例如如何设置超参数、选择合适的学习率调度器等。

    电子信息工程巴特沃斯低通滤波器设计与仿真

    打包了西安电子科技大学B级测试低通滤波器设计,属于巴特沃斯低通滤波器,包含电路仿真、报告、matlab仿真,适合初学者以及西电学生作参考使用。

    光电探测器仿真:光电探测器基础理论.zip

    光电材料仿真,电子仿真等;从入门到精通教程;含代码案例解析。

    natsort-6.0.0-py2.py3-none-any.whl

    该资源为natsort-6.0.0-py2.py3-none-any.whl,欢迎下载使用哦!

    这篇文章详细介绍了基于积分时滞模型(Integral Delay Model, ID Model)的渠道水位预测控制算法的研究与实现,主要围绕模型预测控制(MPC)展开 论文复现或解答具体内容如下:

    内容概要:本文详细介绍了基于积分时滞模型(ID Model)的渠道水位预测控制算法,主要聚焦于模型预测控制(MPC)框架下的实现。文章首先概述了论文的核心内容,即通过MPC结合渠道仿真模型和简化预测模型来实现水位控制。接着,通过详细的代码实现展示了从环境准备、渠道参数设置、SWMM模型构建、简化预测模型、MPC控制器实现到最后的完整仿真流程。文中还深入解析了积分时滞模型的数学原理及其参数辨识方法,并通过状态空间模型构建和滚动优化策略,实现了多渠段渠道水位的精准控制。此外,文章还提供了完整的性能评估和可视化展示,确保算法的有效性和适应性。 适合人群:具备一定编程基础,尤其是熟悉Python编程语言的研发人员,以及从事水利、自动化控制领域研究的专业人士。 使用场景及目标:①帮助读者理解如何利用SWMM模型和MPC算法实现渠道水位控制;②掌握积分时滞模型的数学原理及其在预测控制中的应用;③学习如何通过Python代码实现从模型构建到性能评估的完整流程;④提供实际案例,便于研究人员和工程师在实际项目中应用和改进该算法。 其他说明:本文不仅提供了详细的代码实现和理论解析,还强调了实际应用中的关键技术和创新点。读者可以通过跟随代码逐步实践,深入理解MPC在渠道水位控制中的应用,并根据具体需求进行扩展和优化。

    espidf启动流程基于esp32c3

    espidf启动流程

Global site tag (gtag.js) - Google Analytics