java中excel导入\导出工具类

时间:2023-02-25 10:42:41

1.导入工具

 package com.linrain.jcs.test;

 import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet; import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*; /**
* @Description: 导入excel工具类
* @CreateDate: 2019/1/24/0024$ 19:39$
* @Version: 1.0
*/
public class ImportExcelUtil { /**
* @param in :承载着Excel的输入流
* @param :要导入的工作表序号
* @param entityClass :List中对象的类型(Excel中的每一行都要转化为该类型的对象)
* @param fieldMap :Excel中的中文列头和类的英文属性的对应关系Map
* @param uniqueFields :指定业务主键组合(即复合主键),这些列的组合不能重复
* @return :List
* @throws ExcelException
* @MethodName : excelToList
* @Description : 将Excel转化为List
*/
public static <T> List<T> excelToList(InputStream in, String sheetName, Class<T> entityClass,
LinkedHashMap<String, String> fieldMap, String[] uniqueFields) throws ExcelException { //定义要返回的list
List<T> resultList = new ArrayList<T>(); try { //根据Excel数据源创建WorkBook
Workbook wb = Workbook.getWorkbook(in);
//获取工作表
Sheet sheet = wb.getSheet(sheetName); //获取工作表的有效行数
int realRows = 0;
for (int i = 0; i < sheet.getRows(); i++) { int nullCols = 0;
for (int j = 0; j < sheet.getColumns(); j++) {
Cell currentCell = sheet.getCell(j, i);
if (currentCell == null || "".equals(currentCell.getContents().toString())) {
nullCols++;
}
} if (nullCols == sheet.getColumns()) {
break;
} else {
realRows++;
}
} //如果Excel中没有数据则提示错误
if (realRows <= 1) {
throw new ExcelException("Excel文件中没有任何数据");
} Cell[] firstRow = sheet.getRow(0); String[] excelFieldNames = new String[firstRow.length]; //获取Excel中的列名
for (int i = 0; i < firstRow.length; i++) {
excelFieldNames[i] = firstRow[i].getContents().toString().trim();
} //判断需要的字段在Excel中是否都存在
boolean isExist = true;
List<String> excelFieldList = Arrays.asList(excelFieldNames);
for (String cnName : fieldMap.keySet()) {
if (!excelFieldList.contains(cnName)) {
isExist = false;
break;
}
} //如果有列名不存在,则抛出异常,提示错误
if (!isExist) {
throw new ExcelException("Excel中缺少必要的字段,或字段名称有误");
} //将列名和列号放入Map中,这样通过列名就可以拿到列号
LinkedHashMap<String, Integer> colMap = new LinkedHashMap<String, Integer>();
for (int i = 0; i < excelFieldNames.length; i++) {
colMap.put(excelFieldNames[i], firstRow[i].getColumn());
} //判断是否有重复行
//1.获取uniqueFields指定的列
Cell[][] uniqueCells = new Cell[uniqueFields.length][];
for (int i = 0; i < uniqueFields.length; i++) {
int col = colMap.get(uniqueFields[i]);
uniqueCells[i] = sheet.getColumn(col);
} //2.从指定列中寻找重复行
for (int i = 1; i < realRows; i++) {
int nullCols = 0;
for (int j = 0; j < uniqueFields.length; j++) {
String currentContent = uniqueCells[j][i].getContents();
Cell sameCell = sheet.findCell(currentContent,
uniqueCells[j][i].getColumn(),
uniqueCells[j][i].getRow() + 1,
uniqueCells[j][i].getColumn(),
uniqueCells[j][realRows - 1].getRow(),
true);
if (sameCell != null) {
nullCols++;
}
} if (nullCols == uniqueFields.length) {
throw new ExcelException("Excel中有重复行,请检查");
}
} //将sheet转换为list
for (int i = 1; i < realRows; i++) {
//新建要转换的对象
T entity = entityClass.newInstance(); //给对象中的字段赋值
for (Map.Entry<String, String> entry : fieldMap.entrySet()) {
//获取中文字段名
String cnNormalName = entry.getKey();
//获取英文字段名
String enNormalName = entry.getValue();
//根据中文字段名获取列号
int col = colMap.get(cnNormalName); //获取当前单元格中的内容
String content = sheet.getCell(col, i).getContents().toString().trim(); //给对象赋值
setFieldValueByName(enNormalName, content, entity);
} resultList.add(entity);
}
} catch (Exception e) {
e.printStackTrace();
//如果是ExcelException,则直接抛出
if (e instanceof ExcelException) {
throw (ExcelException) e; //否则将其它异常包装成ExcelException再抛出
} else {
e.printStackTrace();
throw new ExcelException("导入Excel失败");
}
}
return resultList;
} /**
* 根据字段名给对象的字段赋值
*
* @param fieldName 字段名
* @param fieldValue 字段值
* @param o 对象
* @throws Exception 异常
*/
public static void setFieldValueByName(String fieldName, Object fieldValue, Object o) throws Exception { Field field = getFieldByName(fieldName, o.getClass());
if (field != null) {
field.setAccessible(true);
// 获取字段类型
Class<?> fieldType = field.getType(); // 根据字段类型给字段赋值
if (String.class == fieldType) {
field.set(o, String.valueOf(fieldValue));
} else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) {
field.set(o, Integer.parseInt(fieldValue.toString()));
} else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {
field.set(o, Long.valueOf(fieldValue.toString()));
} else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {
field.set(o, Float.valueOf(fieldValue.toString()));
} else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) {
field.set(o, Short.valueOf(fieldValue.toString()));
} else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) {
field.set(o, Double.valueOf(fieldValue.toString()));
} else if (Character.TYPE == fieldType) {
if ((fieldValue != null) && (fieldValue.toString().length() > 0)) {
field.set(o, Character.valueOf(fieldValue.toString().charAt(0)));
}
} else if (Date.class == fieldType) {
if (!fieldValue.toString().isEmpty()) {
if (fieldValue.toString().length() > 10) { field.set(o, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(fieldValue.toString()));
} else {
field.set(o, new SimpleDateFormat("yyyy-MM-dd").parse(fieldValue.toString()));
}
}
} else {
field.set(o, fieldValue);
}
} else {
throw new ExcelException(o.getClass().getSimpleName() + "类不存在字段名 " + fieldName);
}
} /**
* @param sourceSheet
* @param eSheet 错误列表
* @param errorMap 错误原因
* @throws Exception
* @MethodName : addErrorRow
* @Description : 添加一行错误列表
*/
private void addErrorRow(Sheet sourceSheet, WritableSheet eSheet, LinkedHashMap<Integer, String> errorMap) throws Exception { // 复制错误的数据到错误列表
for (Map.Entry<Integer, String> entry : errorMap.entrySet()) {
int errorNo = entry.getKey();
String reason = entry.getValue();
int rows = eSheet.getRows();
for (int i = 0; i < sourceSheet.getColumns(); i++) {
System.out.println("错误列表当前列号" + i);
eSheet.addCell(new Label(i, rows, sourceSheet.getCell(i, errorNo).getContents()));
} // 添加错误原因和所在行号
eSheet.addCell(new Label(sourceSheet.getColumns(), rows, reason));
eSheet.addCell(new Label(sourceSheet.getColumns() + 1, rows, String.valueOf(errorNo + 1))); } } /**
* 设置工作表自动列宽和首行加粗
*
* @param ws 要设置格式的工作表
* @param extraWith 额外的宽度
*/
public static void setColumnAutoSize(WritableSheet ws, int extraWith) {
// 获取本列的最宽单元格的宽度
for (int i = 0; i < ws.getColumns(); i++) {
int colWith = 0;
for (int j = 0; j < ws.getRows(); j++) {
String content = ws.getCell(i, j).getContents().toString();
int cellWith = content.length();
if (colWith < cellWith) {
colWith = cellWith;
}
}
// 设置单元格的宽度为最宽宽度+额外宽度
ws.setColumnView(i, colWith + extraWith);
} } /**
* 根据字段名获取字段
*
* @param fieldName 字段名
* @param clazz 包含该字段的类
* @return 字段
*/
public static Field getFieldByName(String fieldName, Class<?> clazz) {
// 拿到本类的所有字段
Field[] selfFields = clazz.getDeclaredFields(); // 如果本类中存在该字段,则返回
for (Field field : selfFields) {
if (field.getName().equals(fieldName)) {
return field;
}
} // 否则,查看父类中是否存在此字段,如果有则返回
Class<?> superClazz = clazz.getSuperclass();
if (superClazz != null && superClazz != Object.class) {
return getFieldByName(fieldName, superClazz);
} // 如果本类和父类都没有,则返回空
return null;
} /**
* 根据实体拿到该实体的所有属性
*
* @param clazz 实体
* @return 返回属性的list集合
*/
public static List<String> getSuperClassFieldByClass(Class<?> clazz) { List<String> list = new ArrayList<String>(); // 否则,查看父类中是否存在此字段,如果有则返回
Class<?> superClazz = clazz.getSuperclass(); Field[] superFields = superClazz.getDeclaredFields();
for (Field field : superFields) {
list.add(field.getName());
} // 如果父类没有,则返回空
return list;
} /**
* @param clazz :对象对应的类
* @param equalFields :复合业务主键对应的map
* @return 查询到的对象
* @MethodName : getObjByFields
* @Description :根据复合业务主键查询对象
*/
private <T> T getObjByFields(Class<T> clazz, LinkedHashMap<Object, Object> equalFields) { List<T> list = null;
if (equalFields.size() != 0) {
// list=commonBean.findResultListByEqual(clazz, equalFields);
} return list == null || list.size() == 0 ? null : list.get(0);
} /**
* @param normalFieldMap 普通字段Map
* @param referFieldMap 引用字段Map
* @return 组合后的Map
* @MethodName : combineFields
* @Description : 组合普通和引用中英文字段Map
*/
private LinkedHashMap<String, String> combineFields(LinkedHashMap<String, String> normalFieldMap, LinkedHashMap<LinkedHashMap<String, Class<?>>, LinkedHashMap<String, String>> referFieldMap) { LinkedHashMap<String, String> combineMap = new LinkedHashMap<String, String>(); // 如果存在普通字段,则添加之
if (normalFieldMap != null && normalFieldMap.size() != 0) {
combineMap.putAll(normalFieldMap);
} // 如果存在引用字段,则添加之
if (referFieldMap != null && referFieldMap.size() != 0) { // 组建引用中英文字段Map
LinkedHashMap<String, String> simpleReferFieldMap = new LinkedHashMap<String, String>();
for (Map.Entry<LinkedHashMap<String, Class<?>>, LinkedHashMap<String, String>> entry : referFieldMap.entrySet()) {
LinkedHashMap<String, Class<?>> keyMap = entry.getKey();
LinkedHashMap<String, String> valueMap = entry.getValue(); // 获取引用中文字段名
String referField = "";
for (Map.Entry<String, Class<?>> keyEntry : keyMap.entrySet()) {
referField = keyEntry.getKey();
break;
} for (Map.Entry<String, String> valueEntry : valueMap.entrySet()) {
String enField = valueEntry.getValue();
String cnField = valueEntry.getKey();
// 拼接英文引用字段
String fullEnField = referField + "." + enField; // 放入simpleReferFieldMap
simpleReferFieldMap.put(cnField, fullEnField);
} } // 放入combineMap
combineMap.putAll(simpleReferFieldMap);
} return combineMap; } }

2.导出工具

 package com.linrain.jcs.test;

 import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.Map; /**
* @Description: 导出excel工具类
* @CreateDate: 2019/1/24/ 17:18$
* @Version: 1.0
*/
public class ExportExcelUtil {
/**
* 常用普通文件下载
* @param response
* @param fileName
* @param sheetName
* @param data
*/
public static void down(HttpServletResponse response, String fileName, String sheetName, List<Map<String, Object>> data) {
// 生成提示信息,
response.setContentType("application/vnd.ms-excel");
if (StringUtils.isBlank(fileName)) {
fileName = Long.toString(System.currentTimeMillis());
}
OutputStream fOut = null;
try {
// 进行转码,使其支持中文文件名
fOut = response.getOutputStream();
String codedFileName = new String(fileName.getBytes("gbk"), "iso-8859-1");
response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xls");
HSSFWorkbook workbook = new HSSFWorkbook();
// 产生工作表对象
HSSFSheet sheet = workbook.createSheet(sheetName); for (int i = 0; i < data.size(); i++) {
HSSFRow row = sheet.createRow((int) i);
Map<String, Object> map = data.get(i); //遍历map中的值
int j = 0;
for (Object value : map.values()) {
HSSFCell cell = row.createCell((int) j);
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
if (value == null) {
value = "";
}
cell.setCellValue(value.toString());
j++;
}
}
workbook.write(fOut);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fOut.flush();
fOut.close();
} catch (IOException e) {
}
}
}
}

java中excel导入\导出工具类的更多相关文章

  1. Java基础学习总结&lpar;49&rpar;——Excel导入导出工具类

    在项目的pom文件中引入 <dependency> <groupId>net.sourceforge.jexcelapi</groupId> <artifac ...

  2. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...

  3. java简易excel导入导出工具(封装POI)

    Octopus 如何导入excel 如何导出excel github项目地址 Octopus Octopus 是一个简单的java excel导入导出工具. 如何导入excel 下面是一个excel文 ...

  4. java Excel导入导出工具类

    本文章,导入导出依赖提前定义好的模板 package com.shareworx.yjwy.utils; import java.io.File; import java.io.FileInputSt ...

  5. 【原创】POI操作Excel导入导出工具类ExcelUtil

    关于本类线程安全性的解释: 多数工具方法不涉及共享变量问题,至于添加合并单元格方法addMergeArea,使用ThreadLocal变量存储合并数据,ThreadLocal内部借用Thread.Th ...

  6. Octopus——excel导入导出工具

    Octopus Octopus是一个简易的Excel导入导出工具.目前主要就两个功能: 导入:将excel中一行数据转换为指定的java对象,并通过指定的正则表达式检查合法性. 导出:按照给定的xml ...

  7. Excel导入导出工具(简单、好用且轻量级的海量Excel文件导入导出解决方案&period;)

    Excel导入导出工具(简单.好用且轻量级的海量Excel文件导入导出解决方案.) 置顶 2019-09-07 16:47:10 $9420 阅读数 261更多 分类专栏: java   版权声明:本 ...

  8. Excel导入导出帮助类

    /// <summary>    /// Excel导入导出帮助类    /// 记得引入 NPOI    /// 下载地址   http://npoi.codeplex.com/rele ...

  9. JAVA实现Excel导入&sol;导出【转】

    JAVA实现Excel导入/导出[转] POI的下载与安装 请到网站http://www.apache.org/dyn/closer.cgi/poi/右击超链接2.5.1.zip下载压缩包poi-bi ...

随机推荐

  1. 非阻塞同步算法实战(三)-LatestResultsProvider

    本人是本文的作者,首发于ifeve(非阻塞同步算法实战(三)-LatestResultsProvider) 前言 阅读本文前,需要读者对happens-before比较熟悉,了解非阻塞同步的一些基本概 ...

  2. easyUI的datagrid控件日期列不能正确显示Json格式数据的解决方案

    EasyUI是一套比较轻巧易用的Jquery控件,在使用过程中遇到一个问题,它的列表控件——datagrid, 在显示日期列的时候,由于后台返回给页面的数据是Json格式的,其中的日期字段,在后台是正 ...

  3. oracle 库文件解决的方法 bad ELF interpreter&colon; No such file or directory

    今天是2014-05-27,今天遇到一个lib问题,再次记录一下.这是一个案例,更是一种解决该问题的方法过程. 当我们在使用sqlplus 登陆unix数据库的时候,有可能出现类似:xxxxxx ba ...

  4. 【最大流之sap】【HDU1532】模板题

    与上题一样 纯属测试模板 来自kuangbin的模板 #include <cstdio> #include <cstdlib> #include <cmath> # ...

  5. Python起步

    最近研究系统自动化测试想起了一年前有学习Python的想法,借此机会准备抽时间好好学学.为方便以后学习和查询特写以下博客! Python基础 1. Python数据结构 (1)Python字符串 (2 ...

  6. Java的Random总结

    /** * @Title:RandomNum.java * @Package:com.yhd.chart.model * @Description:Java产生随机数 * @author:Youhai ...

  7. Codeforces Round &num;437 E&period; Buy Low Sell High

    题意:买卖股票,给你n个数,你可以选择买进或者卖出或者什么都不做,问你最后获得的最大收益是多少. Examples Input 910 5 4 7 9 12 6 2 10 Output 20 Inpu ...

  8. gym 101164 H&period;Pub crawl 凸包

    题目链接:http://codeforces.com/gym/101164/attachments 题意:对于已知的 n 个二维坐标点,要求按照某种特定的连线方式将尽可能多的点连接(任意相邻的 3 个 ...

  9. STM32系统时钟为什么没有定义呢

    对于使用3.5版本库开发的STM32学习者 有时候不清楚为什么没有时钟定义 那么我们就简单的讲解下吧: 1,函数从启动文件开始运行(汇编文件) 2,若是hd.s 请看151行LDR     R0, = ...

  10. 最新的Veil3&period;0的安装和使用

    首先安装 ┌─[root@sch01ar]─[~] └──╼ #cd /sch01ar/Veil/ ┌─[root@sch01ar]─[/sch01ar/Veil] └──╼ #cd setup/ ┌ ...