热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

javaExcel表格导入导出

效果图依赖主要为poi和jxl依赖,如下:org.apache.poi
效果图

依赖

主要为 poijxl 依赖,如下:

org.apache.poipoi3.17net.sourceforge.jexcelapijxl2.6.12

核心代码

调用方

后台接收前端传递回来的文件地址,生成字节流:

public ReturnDTO importUserDetails(String path) {ReturnDTO returnDTO = new ReturnDTO();try {path = DirectoryConst.FILE_DIR + path.replace("/files", ""); // 判断文件是否是Excel(2003、2007)String suffix = path.substring(path.lastIndexOf("."), path.length());if (".xls".equalsIgnoreCase(suffix) || ".xlsx".equalsIgnoreCase(suffix)) {// 2003后缀或2007后缀List userList = ExcelUtil.excelToList(new FileInputStream(path),"Sheet1",BkPassportInfoDetailDTO.class,ExcelFieldMap.getFieldMapIn());System.out.println(userList.toString());returnDTO.setResult(commonQueryDAO.importUserDetails(userList));returnDTO.setStatus(StatusConsts.STATUS_SUCCESS);returnDTO.setReturnMsg(StatusConsts.STATUS_SUCCESS_MESSAGE);}else {returnDTO.setStatus(StatusConsts.STATUS_PARAMETER_ERROR);returnDTO.setReturnMsg(StatusConsts.STATUS_PARAMETER_ERROR_MESSAGE);}}catch(Exception e) {e.printStackTrace();returnDTO.setStatus(StatusConsts.STATUS_FAILURE);returnDTO.setReturnMsg(StatusConsts.STATUS_FAILURE_MESSAGE);}return returnDTO;}

ExcelUtil

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
//import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;/*** &#64;Comments : 导入导出Excel工具类*/public class ExcelUtil {/*** &#64;param list 数据源* &#64;param fieldMap 类的英文属性和Excel中的中文列名的对应关系* 如果需要的是引用对象的属性&#xff0c;则英文属性使用类似于EL表达式的格式* 如&#xff1a;list中存放的都是student&#xff0c;student中又有college属性&#xff0c;而我们需要学院名称&#xff0c;则可以这样写* fieldMap.put("college.collegeName","学院名称")* &#64;param sheetName 工作表的名称* &#64;param sheetSize 每个工作表中记录的最大个数* &#64;param out 导出流* &#64;throws ExcelException* &#64;MethodName : listToExcel* &#64;Description : 导出Excel&#xff08;可以导出到本地文件系统&#xff0c;也可以导出到浏览器&#xff0c;可自定义工作表大小&#xff09;*/public static void listToExcel(List list,LinkedHashMap fieldMap,String sheetName,int sheetSize,OutputStream out) throws ExcelException {if (list.size() &#61;&#61; 0 || list &#61;&#61; null) {throw new ExcelException("数据源中没有任何数据");}if (sheetSize > 65535 || sheetSize <1) {sheetSize &#61; 65535;}//创建工作簿并发送到OutputStream指定的地方WritableWorkbook wwb;try {wwb &#61; Workbook.createWorkbook(out);//因为2003的Excel一个工作表最多可以有65536条记录&#xff0c;除去列头剩下65535条//所以如果记录太多&#xff0c;需要放到多个工作表中&#xff0c;其实就是个分页的过程//1.计算一共有多少个工作表double sheetNum &#61; Math.ceil(list.size() / new Integer(sheetSize).doubleValue());//2.创建相应的工作表&#xff0c;并向其中填充数据for (int i &#61; 0; i list.size() - 1 ? list.size() - 1 : (i &#43; 1) * sheetSize - 1;//填充工作表fillSheet(sheet, list, fieldMap, firstIndex, lastIndex);}}wwb.write();wwb.close();} catch (Exception e) {e.printStackTrace();//如果是ExcelException&#xff0c;则直接抛出if (e instanceof ExcelException) {throw (ExcelException) e;//否则将其它异常包装成ExcelException再抛出} else {throw new ExcelException("导出Excel失败");}}}/*** &#64;param list 数据源* &#64;param fieldMap 类的英文属性和Excel中的中文列名的对应关系* &#64;param out 导出流* &#64;throws ExcelException* &#64;MethodName : listToExcel* &#64;Description : 导出Excel&#xff08;可以导出到本地文件系统&#xff0c;也可以导出到浏览器&#xff0c;工作表大小为2003支持的最大值&#xff09;*/public static void listToExcel(List list,LinkedHashMap fieldMap,String sheetName,OutputStream out) throws ExcelException {listToExcel(list, fieldMap, sheetName, 65535, out);}/*** 不去重*/public static List excelToList(InputStream in,String sheetName,Class entityClass,LinkedHashMap fieldMap) throws ExcelException {return excelToList(in, sheetName, entityClass, fieldMap, null);}/*** 去重复字段 需要把重复字段写出来** &#64;param in &#xff1a;承载着Excel的输入流* &#64;param entityClass &#xff1a;List中对象的类型&#xff08;Excel中的每一行都要转化为该类型的对象&#xff09;* &#64;param fieldMap &#xff1a;Excel中的中文列头和类的英文属性的对应关系Map* &#64;param uniqueFields &#xff1a;指定业务主键组合&#xff08;即复合主键&#xff09;&#xff0c;这些列的组合不能重复* &#64;return &#xff1a;List* &#64;throws ExcelException* &#64;MethodName : excelToList* &#64;Description : 将Excel转化为List*/public static List excelToList(InputStream in,String sheetName,Class entityClass,LinkedHashMap fieldMap,String[] uniqueFields) throws ExcelException {//定义要返回的listList resultList &#61; new ArrayList();try {//根据Excel数据源创建WorkBookWorkbook wb &#61; Workbook.getWorkbook(in);//获取工作表Sheet sheet &#61; wb.getSheet(sheetName);//获取工作表的有效行数int realRows &#61; 0;for (int i &#61; 0; i excelFieldList &#61; Arrays.asList(excelFieldNames);for (String cnName : fieldMap.keySet()) {if (!excelFieldList.contains(cnName)) {isExist &#61; false;break;}}//如果有列名不存在&#xff0c;则抛出异常&#xff0c;提示错误if (!isExist) {throw new ExcelException("Excel中缺少必要的字段&#xff0c;或字段名称有误");}//将列名和列号放入Map中,这样通过列名就可以拿到列号LinkedHashMap colMap &#61; new LinkedHashMap();for (int i &#61; 0; i entry : fieldMap.entrySet()) {//获取中文字段名String cnNormalName &#61; entry.getKey();//获取英文字段名String enNormalName &#61; entry.getValue();//根据中文字段名获取列号int col &#61; colMap.get(cnNormalName);//获取当前单元格中的内容String content &#61; sheet.getCell(col, i).getContents().toString().trim();//给对象赋值setFieldValueByName(enNormalName, content, entity);}resultList.add(entity);}} catch (Exception e) {e.printStackTrace();//如果是ExcelException&#xff0c;则直接抛出if (e instanceof ExcelException) {throw (ExcelException) e;//否则将其它异常包装成ExcelException再抛出} else {e.printStackTrace();throw new ExcelException("导入Excel失败");}}return resultList;}/*<-------------------------辅助的私有方法----------------------------------------------->*//*** &#64;param fieldName 字段名* &#64;param o 对象* &#64;return 字段值* &#64;MethodName : getFieldValueByName* &#64;Description : 根据字段名获取字段值*/private static Object getFieldValueByName(String fieldName, Object o) throws Exception {Object value &#61; null;Field field &#61; getFieldByName(fieldName, o.getClass());if (field !&#61; null) {field.setAccessible(true);value &#61; field.get(o);} else {throw new ExcelException(o.getClass().getSimpleName() &#43; "类不存在字段名 " &#43; fieldName);}return value;}/*** &#64;param fieldName 字段名* &#64;param clazz 包含该字段的类* &#64;return 字段* &#64;MethodName : getFieldByName* &#64;Description : 根据字段名获取字段*/private static Field getFieldByName(String fieldName, Class clazz) {//拿到本类的所有字段Field[] selfFields &#61; clazz.getDeclaredFields();//如果本类中存在该字段&#xff0c;则返回for (Field field : selfFields) {if (field.getName().equals(fieldName)) {return field;}}//否则&#xff0c;查看父类中是否存在此字段&#xff0c;如果有则返回Class superClazz &#61; clazz.getSuperclass();if (superClazz !&#61; null && superClazz !&#61; Object.class) {return getFieldByName(fieldName, superClazz);}//如果本类和父类都没有&#xff0c;则返回空return null;}/*** &#64;param fieldNameSequence 带路径的属性名或简单属性名* &#64;param o 对象* &#64;return 属性值* &#64;throws Exception* &#64;MethodName : getFieldValueByNameSequence* &#64;Description :* 根据带路径或不带路径的属性名获取属性值* 即接受简单属性名&#xff0c;如userName等&#xff0c;又接受带路径的属性名&#xff0c;如student.department.name等*/private static Object getFieldValueByNameSequence(String fieldNameSequence, Object o) throws Exception {Object value &#61; null;//将fieldNameSequence进行拆分String[] attributes &#61; fieldNameSequence.split("\\.");if (attributes.length &#61;&#61; 1) {value &#61; getFieldValueByName(fieldNameSequence, o);} else {//根据属性名获取属性对象Object fieldObj &#61; getFieldValueByName(attributes[0], o);String subFieldNameSequence &#61; fieldNameSequence.substring(fieldNameSequence.indexOf(".") &#43; 1);value &#61; getFieldValueByNameSequence(subFieldNameSequence, fieldObj);}return value;}/*** &#64;param fieldName 字段名* &#64;param fieldValue 字段值* &#64;param o 对象* &#64;MethodName : setFieldValueByName* &#64;Description : 根据字段名给对象的字段赋值*/private static void setFieldValueByName(String fieldName, Object fieldValue, Object o) throws Exception {Field field &#61; getFieldByName(fieldName, o.getClass());if (field !&#61; null) {field.setAccessible(true);//获取字段类型Class fieldType &#61; field.getType();//根据字段类型给字段赋值if (String.class &#61;&#61; fieldType) {field.set(o, String.valueOf(fieldValue));} else if ((Integer.TYPE &#61;&#61; fieldType)|| (Integer.class &#61;&#61; fieldType)) {field.set(o, Integer.parseInt(fieldValue.toString()));} else if ((Long.TYPE &#61;&#61; fieldType)|| (Long.class &#61;&#61; fieldType)) {field.set(o, Long.valueOf(fieldValue.toString()));} else if ((Float.TYPE &#61;&#61; fieldType)|| (Float.class &#61;&#61; fieldType)) {field.set(o, Float.valueOf(fieldValue.toString()));} else if ((Short.TYPE &#61;&#61; fieldType)|| (Short.class &#61;&#61; fieldType)) {field.set(o, Short.valueOf(fieldValue.toString()));} else if ((Double.TYPE &#61;&#61; fieldType)|| (Double.class &#61;&#61; fieldType)) {field.set(o, Double.valueOf(fieldValue.toString()));} else if (Character.TYPE &#61;&#61; fieldType) {if ((fieldValue !&#61; null) && (fieldValue.toString().length() > 0)) {field.set(o, Character.valueOf(fieldValue.toString().charAt(0)));}} else if (Date.class &#61;&#61; fieldType) {field.set(o, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(fieldValue.toString()));}else if(BigDecimal.class &#61;&#61; fieldType){field.set(o, new BigDecimal(fieldValue.toString()));}else {field.set(o, fieldValue);}} else {throw new ExcelException(o.getClass().getSimpleName() &#43; "类不存在字段名 " &#43; fieldName);}}/*** &#64;param ws* &#64;MethodName : setColumnAutoSize* &#64;Description : 设置工作表自动列宽和首行加粗*/private static void setColumnAutoSize(WritableSheet ws, int extraWith) {//获取本列的最宽单元格的宽度for (int i &#61; 0; i void fillSheet(WritableSheet sheet,List list,LinkedHashMap fieldMap,int firstIndex,int lastIndex) throws Exception {//定义存放英文字段名和中文字段名的数组String[] enFields &#61; new String[fieldMap.size()];String[] cnFields &#61; new String[fieldMap.size()];//填充数组int count &#61; 0;for (Map.Entry entry : fieldMap.entrySet()) {enFields[count] &#61; entry.getKey();cnFields[count] &#61; entry.getValue();count&#43;&#43;;}//填充表头for (int i &#61; 0; i

ExcelFieldMap映射

表格的标题要和字段一一对应&#xff0c;这里导入用的是 getFieldMapIn() 方法。

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;public class ExcelFieldMap {/*** 字段排名列*导出excel* &#64;return*/public static LinkedHashMap getFieldMapOut() {LinkedHashMap linkedHashMap &#61; new LinkedHashMap();linkedHashMap.put("phone", "联系电话");linkedHashMap.put("realName", "真实姓名");linkedHashMap.put("department", "机构"); linkedHashMap.put("email", "电子邮箱");linkedHashMap.put("money", "金额");return linkedHashMap;}/*** 字段排序* 导入excel*/public static LinkedHashMap getFieldMapIn() {LinkedHashMap linkedHashMap &#61; new LinkedHashMap();Iterator iter &#61; getFieldMapOut().entrySet().iterator();while (iter.hasNext()) {Map.Entry entry &#61; (Map.Entry) iter.next();String key &#61; (String) entry.getKey();String val &#61; (String) entry.getValue();linkedHashMap.put(val,key);}return linkedHashMap;}}

ExcelException

自定义异常&#xff1a;


/*** 自定义异常*/
public class ExcelException extends Exception{public ExcelException() {// TODO Auto-generated constructor stub}public ExcelException(String message) {super(message);// TODO Auto-generated constructor stub}public ExcelException(Throwable cause) {super(cause);// TODO Auto-generated constructor stub}public ExcelException(String message, Throwable cause) {super(message, cause);// TODO Auto-generated constructor stub}
}

可直接下载源码运行&#xff1a; https://download.csdn.net/download/she_lock/10603000


推荐阅读
  • 本文介绍了如何使用JavaScript的Fetch API与Express服务器进行交互,涵盖了GET、POST、PUT和DELETE请求的实现,并展示了如何处理JSON响应。 ... [详细]
  • 使用Nginx反向代理实现多域名端口映射
    本文介绍如何通过配置本地hosts文件和Nginx反向代理,实现多个虚拟域名的端口映射,使用户可以通过标准HTTP端口80访问不同后端服务。 ... [详细]
  • 云函数与数据库API实现增删查改的对比
    本文将深入探讨使用云函数和数据库API实现数据操作(增删查改)的不同方法,通过详细的代码示例帮助读者更好地理解和掌握这些技术。文章不仅提供代码实现,还解释了每种方法的特点和适用场景。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 本文探讨了如何利用HTML5和JavaScript在浏览器中进行本地文件的读取和写入操作,并介绍了获取本地文件路径的方法。HTML5提供了一系列API,使得这些操作变得更加简便和安全。 ... [详细]
  • 中科院学位论文排版指南
    随着毕业季的到来,许多即将毕业的学生开始撰写学位论文。本文介绍了使用LaTeX排版学位论文的方法,特别是针对中国科学院大学研究生学位论文撰写规范指导意见的最新要求。LaTeX以其精确的控制和美观的排版效果成为许多学者的首选。 ... [详细]
  • Hadoop发行版本选择指南:技术解析与应用实践
    本文详细介绍了Hadoop的不同发行版本及其特点,帮助读者根据实际需求选择最合适的Hadoop版本。内容涵盖Apache Hadoop、Cloudera CDH等主流版本的特性及应用场景。 ... [详细]
  • Qt QTableView 内嵌控件的实现方法
    本文详细介绍了在 Qt QTableView 中嵌入控件的多种方法,包括使用 QItemDelegate、setIndexWidget 和 setIndexWidget 结合布局管理器。每种方法都有其适用场景和优缺点。 ... [详细]
  • This post discusses an issue encountered while using the @name annotation in documentation generation, specifically regarding nested class processing and unexpected output. ... [详细]
  • ElasticSearch 集群监控与优化
    本文详细介绍了如何有效地监控 ElasticSearch 集群,涵盖了关键性能指标、集群健康状况、统计信息以及内存和垃圾回收的监控方法。 ... [详细]
  • ssm框架整合及工程分层1.先创建一个新的project1.1配置pom.xml ... [详细]
  • 本文详细介绍了如何在云服务器上配置Nginx、Tomcat、JDK和MySQL。涵盖从下载、安装到配置的完整步骤,帮助读者快速搭建Java Web开发环境。 ... [详细]
  • 本文探讨了如何在Hive(基于Hadoop)环境中编写类似SQL的语句,以去除字段中的空格。特别是在处理邮政编码等数据时,去除特定位置的空格是常见的需求。 ... [详细]
  • 本文详细介绍了如何解压并安装MySQL集群压缩包,创建用户和组,初始化数据库,配置环境变量,并启动相关服务。此外,还提供了详细的命令行操作步骤和常见问题的解决方案。 ... [详细]
author-avatar
歪果仁
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有