热门标签 | 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


推荐阅读
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 问题场景用Java进行web开发过程当中,当遇到很多很多个字段的实体时,最苦恼的莫过于编辑字段的查看和修改界面,发现2个页面存在很多重复信息,能不能写一遍?有没有轮子用都不如自己造。解决方式笔者根据自 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 本文介绍了如何通过C#语言调用动态链接库(DLL)中的函数来实现IC卡的基本操作,包括初始化设备、设置密码模式、获取设备状态等,并详细展示了将TextBox中的数据写入IC卡的具体实现方法。 ... [详细]
  • spring boot使用jetty无法启动 ... [详细]
  • 本文探讨了如何通过Service Locator模式来简化和优化在B/S架构中的服务命名访问,特别是对于需要频繁访问的服务,如JNDI和XMLNS。该模式通过缓存机制减少了重复查找的成本,并提供了对多种服务的统一访问接口。 ... [详细]
  • Android与JUnit集成测试实践
    本文探讨了如何在Android项目中集成JUnit进行单元测试,并详细介绍了修改AndroidManifest.xml文件以支持测试的方法。 ... [详细]
  • importjava.io.*;importjava.util.*;publicclass五子棋游戏{staticintm1;staticintn1;staticfinalintS ... [详细]
  • 本文详细探讨了 Java 中 org.apache.gobblin.metrics.GobblinMetrics 类下的 getName() 方法的使用场景及其代码实现,提供了多个实际应用示例以加深理解。 ... [详细]
  • 在尝试使用 Android 发送 SOAP 请求时遇到错误,服务器返回 '无法处理请求' 的信息,并指出某个值不能为 null。本文探讨了可能的原因及解决方案。 ... [详细]
  • 在Qt框架中,信号与槽机制是一种独特的组件间通信方式。本文探讨了这一机制相较于传统的C风格回调函数所具有的优势,并分析了其潜在的不足之处。 ... [详细]
  • 本文详细介绍了Elasticsearch中的分页查询机制,包括基本的分页查询流程、'from-size'浅分页与'scroll'深分页的区别及应用场景,以及两者在性能上的对比。 ... [详细]
  • 使用QT构建基础串口辅助工具
    本文详细介绍了如何利用QT框架创建一个简易的串口助手应用程序,包括项目的建立、界面设计与编程实现、运行测试以及最终的应用程序打包。 ... [详细]
  • Logging all MySQL queries into the Slow Log
    MySQLoptionallylogsslowqueriesintotheSlowQueryLog–orjustSlowLog,asfriendscallit.However,Thereareseveralreasonstologallqueries.Thislistisnotexhaustive:Belowyoucanfindthevariablestochange,astheyshouldbewritteninth ... [详细]
  • flea,frame,db,使用,之 ... [详细]
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社区 版权所有