步骤一、自定义注解

步骤二、写Excel泛型工具类

步骤三、在需要导出excel的类属相上加上自定义注解,并设置

步骤四、写service,controller

步骤一:自定义注解

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)

@Target({java.lang.annotation.ElementType.FIELD})

public @interface ExcelField {

/**

* 导出到Excel中的名字.

*/

public abstract String name();

/**

* 配置列的名称,对应A,B,C,D....

*/

public abstract String column();

/**

* 提示信息

*/

public abstract String prompt() default "";

/**

* 设置只能选择不能输入的列内容.

*/

public abstract String[] combo() default {};

/**

* 是否导出数据

*/

public abstract boolean isExport() default true;

}

步骤二、excel泛型工具类

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.apache.poi.hssf.usermodel.DVConstraint;

import org.apache.poi.hssf.usermodel.HSSFCell;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;

import org.apache.poi.hssf.usermodel.HSSFDataValidation;

import org.apache.poi.hssf.usermodel.HSSFRow;

import org.apache.poi.hssf.usermodel.HSSFSheet;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.hssf.util.HSSFColor;

import org.apache.poi.ss.util.CellRangeAddressList;

/**

* 导出excel的工具类

* 全部采用string类型,如果需要加入其它类型需要修改工具方法

*/

public class ExcelUtil<T> {

Class<T> clazz;

public ExcelUtil(Class<T> clazz) {

this.clazz = clazz;

}

/**

* 批量导入

* 这里的批量导入指的是一个excel文件中有多个相同类型的sheet页

*/

public List<T> importBatch(InputStream input) throws Exception {

List<T> newList = new ArrayList<T>();

HSSFWorkbook workbook=new HSSFWorkbook(input);

if(null != workbook){

int sheets = workbook.getNumberOfSheets();

if(sheets>0){

for(int i=0;i<sheets;i++){

HSSFSheet sheet = workbook.getSheetAt(i);

if(null != sheet){

List<T> importProcessor = importProcessor(sheet);

newList.addAll(importProcessor);

}

}

}

}

return newList;

}

/**

* 指定sheet页导入,如果不指定默认会选第一个sheet

*/

public List<T> importExcel(String sheetName, InputStream input) throws Exception {

HSSFWorkbook workbook = new HSSFWorkbook(input);

HSSFSheet sheet = workbook.getSheet(sheetName);

if (!sheetName.trim().equals("")) {

sheet = workbook.getSheet(sheetName);// 如果指定sheet名,则取指定sheet中的内容.

}

if (sheet == null) {

sheet = workbook.getSheetAt(0); // 如果传入的sheet名不存在则默认指向第1个sheet.

}

return importProcessor(sheet);

}

/**

* 具体处理导入

*/

private List<T> importProcessor(HSSFSheet sheet) throws Exception {

int maxCol = 0;

List<T> list = new ArrayList<T>();

int rows = sheet.getPhysicalNumberOfRows();

if (rows > 0) {// 有数据时才处理

// Field[] allFields = clazz.getDeclaredFields();// 得到类的所有field.

List<Field> allFields = getMappedFiled(clazz, null);

Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>();// 定义一个map用于存放列的序号和field.

for (Field field : allFields) {

// 将有注解的field存放到map中.

if (field.isAnnotationPresent(ExcelField.class)) {

ExcelField attr = field

.getAnnotation(ExcelField.class);

int col = getExcelCol(attr.column());// 获得列号

maxCol = Math.max(col, maxCol);

// System.out.println(col + "====" + field.getName());

field.setAccessible(true);// 设置类的私有字段属性可访问.

fieldsMap.put(col, field);

}

}

for (int i = 1; i < rows; i++) {// 从第2行开始取数据,默认第一行是表头.

HSSFRow row = sheet.getRow(i);

// int cellNum = row.getPhysicalNumberOfCells();

// int cellNum = row.getLastCellNum();

int cellNum = maxCol;

T entity = null;

for (int j = 0; j <= cellNum; j++) {

HSSFCell cell = row.getCell(j);

if (cell == null) {

continue;

}

int cellType = cell.getCellType();

String c = "";

if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {

c = String.valueOf(cell.getNumericCellValue());

} else if (cellType == HSSFCell.CELL_TYPE_BOOLEAN) {

c = String.valueOf(cell.getBooleanCellValue());

} else {

c = cell.getStringCellValue();

}

if (c == null || c.equals("")) {

continue;

}

entity = (entity == null ? clazz.newInstance() : entity);// 如果不存在实例则新建.

// System.out.println(cells[j].getContents());

Field field = fieldsMap.get(j);// 从map中得到对应列的field.

if (field==null) {

continue;

}

// 取得类型,并根据对象类型设置值.

Class<?> fieldType = field.getType();

if (String.class == fieldType) {

field.set(entity, String.valueOf(c));

} else if ((Integer.TYPE == fieldType)

|| (Integer.class == fieldType)) {

field.set(entity, Integer.parseInt(c));

} else if ((Long.TYPE == fieldType)

|| (Long.class == fieldType)) {

field.set(entity, Long.valueOf(c));

} else if ((Float.TYPE == fieldType)

|| (Float.class == fieldType)) {

field.set(entity, Float.valueOf(c));

} else if ((Short.TYPE == fieldType)

|| (Short.class == fieldType)) {

field.set(entity, Short.valueOf(c));

} else if ((Double.TYPE == fieldType)

|| (Double.class == fieldType)) {

field.set(entity, Double.valueOf(c));

} else if (Character.TYPE == fieldType) {

if ((c != null) && (c.length() > 0)) {

field.set(entity, Character

.valueOf(c.charAt(0)));

}

}

}

if (entity != null) {

list.add(entity);

}

}

}

return list;

}

/**

* 对list数据源将其里面的数据导出到excel表单

*/

public boolean exportExcel(List<T> lists[], String sheetNames[], OutputStream output) {

if (lists.length != sheetNames.length) {

return false;

}

HSSFWorkbook workbook = new HSSFWorkbook();// 产生工作薄对象

for (int ii = 0; ii < lists.length; ii++) {

List<T> list = lists[ii];

String sheetName = sheetNames[ii];

List<Field> fields = getMappedFiled(clazz, null);

HSSFSheet sheet = workbook.createSheet();// 产生工作表对象

workbook.setSheetName(ii, sheetName);

HSSFRow row;

HSSFCell cell;// 产生单元格

HSSFCellStyle style = workbook.createCellStyle();

style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);

style.setFillBackgroundColor(HSSFColor.GREY_40_PERCENT.index);

row = sheet.createRow(0);// 产生一行

for (int i = 0; i < fields.size(); i++) {

Field field = fields.get(i);

ExcelField attr = field.getAnnotation(ExcelField.class);

int col = getExcelCol(attr.column());// 获得列号

cell = row.createCell(col);// 创建列

cell.setCellType(HSSFCell.CELL_TYPE_STRING);// 设置列中写入内容为String类型

cell.setCellValue(attr.name());// 写入列名

if (!attr.prompt().trim().equals("")) {

setHSSFPrompt(sheet, "", attr.prompt(), 1, 100, col, col);// 这里默认设了2-101列提示.

}

if (attr.combo().length > 0) {

setHSSFValidation(sheet, attr.combo(), 1, 100, col, col);// 这里默认设了2-101列只能选择不能输入.

}

cell.setCellStyle(style);

}

int startNo = 0;

int endNo = list.size();

for (int i = startNo; i < endNo; i++) {

row = sheet.createRow(i + 1 - startNo);

T vo = (T) list.get(i);

for (int j = 0; j < fields.size(); j++) {

Field field = fields.get(j);

field.setAccessible(true);

ExcelField attr = field.getAnnotation(ExcelField.class);

try {

if (attr.isExport()) {

cell = row.createCell(getExcelCol(attr.column()));

cell.setCellType(HSSFCell.CELL_TYPE_STRING);

cell.setCellValue(field.get(vo) == null ? ""

: String.valueOf(field.get(vo)));

}

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

}

}

}

try {

output.flush();

workbook.write(output);

output.close();

return true;

} catch (IOException e) {

e.printStackTrace();

return false;

}

}

/**

* 对list数据源将其里面的数据导出到excel表单

*/

@SuppressWarnings("unchecked")

public boolean exportExcel(List<T> list, String sheetName,

OutputStream output) {

//此处 对类型进行转换

List<T> ilist = new ArrayList<>();

for (T t : list) {

ilist.add(t);

}

List<T>[] lists = new ArrayList[1];

lists[0] = ilist;

String[] sheetNames = new String[1];

sheetNames[0] = sheetName;

return exportExcel(lists, sheetNames, output);

}

/**

* 将EXCEL中A,B,C,D,E列映射成0,1,2,3,4

* @param col

*/

public static int getExcelCol(String col) {

col = col.toUpperCase();

// 从-1开始计算,字母重1开始运算。这种总数下来算数正好相同。

int count = -1;

char[] cs = col.toCharArray();

for (int i = 0; i < cs.length; i++) {

count += (cs[i] - 64) * Math.pow(26, cs.length - 1 - i);

}

return count;

}

/**

* 设置单元格上提示

*/

public static HSSFSheet setHSSFPrompt(HSSFSheet sheet, String promptTitle,

String promptContent, int firstRow, int endRow, int firstCol,

int endCol) {

DVConstraint constraint = DVConstraint

.createCustomFormulaConstraint("DD1");

CellRangeAddressList regions = new CellRangeAddressList(firstRow,

endRow, firstCol, endCol);

HSSFDataValidation data_validation_view = new HSSFDataValidation(

regions, constraint);

data_validation_view.createPromptBox(promptTitle, promptContent);

sheet.addValidationData(data_validation_view);

return sheet;

}

/**

* 设置某些列的值只能输入预制的数据,显示下拉框.

*/

public static HSSFSheet setHSSFValidation(HSSFSheet sheet,

String[] textlist, int firstRow, int endRow, int firstCol,

int endCol) {

DVConstraint constraint = DVConstraint

.createExplicitListConstraint(textlist);

CellRangeAddressList regions = new CellRangeAddressList(firstRow,

endRow, firstCol, endCol);

HSSFDataValidation data_validation_list = new HSSFDataValidation(

regions, constraint);

sheet.addValidationData(data_validation_list);

return sheet;

}

/**

* 得到实体类所有通过注解映射了数据表的字段

*  递归调用

*/

private List<Field> getMappedFiled(Class clazz, List<Field> fields) {

if (fields == null) {

fields = new ArrayList<Field>();

}

Field[] allFields = clazz.getDeclaredFields();// 得到所有定义字段

for (Field field : allFields) {

if (field.isAnnotationPresent(ExcelField.class)) {

fields.add(field);

}

}

if (clazz.getSuperclass() != null

&& !clazz.getSuperclass().equals(Object.class)) {

getMappedFiled(clazz.getSuperclass(), fields);

}

return fields;

}

}

步骤三、需要导出的java类属性上加上自定义注解

/**

* 退款excel导出

*/

public class ExcelPackageRefund {

@ExcelField(name="订单",column="A")

private String orderSn;//订单

@ExcelField(name="包裹",column="B")

private String packageSn;//包裹

//setter/getter

}

四、service和cotroller(字数限制,只保留了核心)

response.setHeader("Content-Disposition", "attachment;filename="+new String(filename.getBytes("utf-8"),"iso8859-1"));

response.setContentType("application/ynd.ms-excel;charset=UTF-8");

List<ExcelPackageRefund> packageReturn = excelExportService.exportPackageRefund(bean);

ExcelUtil<ExcelPackageRefund> prbs = new ExcelUtil<ExcelPackageRefund>(ExcelPackageRefund.class);

boolean result = prbs.exportExcel(packageReturn, sheetName,response.getOutputStream());

170313、poi:采用自定义注解的方式导入、导出excel(这种方式比较好扩展)的更多相关文章

  1. Java基于注解和反射导入导出Excel

    代码地址如下:http://www.demodashi.com/demo/11995.html 1. 构建项目 使用Spring Boot快速构建一个Web工程,并导入与操作Excel相关的POI包以 ...

  2. Java利用POI导入导出Excel中的数据

         首先谈一下今天发生的一件开心的事,本着一颗android的心我被分配到了PB组,身在曹营心在汉啊!好吧,今天要记录和分享的是Java利用POI导入导出Excel中的数据.下面POI包的下载地 ...

  3. C#中缓存的使用 ajax请求基于restFul的WebApi(post、get、delete、put) 让 .NET 更方便的导入导出 Excel .net core api +swagger(一个简单的入门demo 使用codefirst+mysql) C# 位运算详解 c# 交错数组 c# 数组协变 C# 添加Excel表单控件(Form Controls) C#串口通信程序

    C#中缓存的使用   缓存的概念及优缺点在这里就不多做介绍,主要介绍一下使用的方法. 1.在ASP.NET中页面缓存的使用方法简单,只需要在aspx页的顶部加上一句声明即可:  <%@ Outp ...

  4. 通过自定义拦截器优雅的导出Excel并标红的重复数据

    平时我们导入导出Excel的时候如果用poi导出,会发现光设置格式都要很多代码,看起来非常的不优雅.后来业务中遇到了需要导入非常巨大的Excel的需求.如果继续用poi的方式,因为poi把所有exce ...

  5. 导入导出Excel工具类ExcelUtil

    前言 前段时间做的分布式集成平台项目中,许多模块都用到了导入导出Excel的功能,于是决定封装一个ExcelUtil类,专门用来处理Excel的导入和导出 本项目的持久化层用的是JPA(底层用hibe ...

  6. C#导入导出Excel表的数据

    一:C#导入导出EXCEL文件的类 代码如下: 首先将Microsoft Excel 14.0 Object Library 引用导入 using System; using System.Data; ...

  7. 导入导出Excel的Java工具类ExcelUtil

    在编写ExcelUtil之前,在网上查了一些资料.java中用来处理Excel的第三方开源项目主要就是POI和JXL.poi功能强大,但是比较耗资源,对于大数据量的导入导出性能不是太好:jxl功能简单 ...

  8. 让 .NET 更方便的导入导出 Excel

    让 .Net 更方便的导入导出Excel Intro 因为前一段时间需要处理一些 excel 数据,主要是导入/导出操作,将 Excel 数据转化为对象再用程序进行处理和分析,没有找到比较满意的库,于 ...

  9. 导入导出Excel文件

    搭建环境 先新建web project ,然后Add Struts Capabilties: 下载导入导出Excel所需的jar包: poi-3.8-20120326.jar包  :  http:// ...

随机推荐

  1. 交叉编译Node.js到OpenWrt(HG255D)

    操作系统:deepin linux 2013 或 ubuntu 13.04 1.安装交叉编译前.须要安装的包 sudo apt-get install build-essential subversi ...

  2. 二级指针 (C语言)

    二级指针又叫双指针.C语言中不存在引用,所以当你试图改变一个指针的值的时候必须使用二级指针.C++中可以使用引用类型来实现. 下面讲解C中的二级指针的使用方法. 例如我们使用指针来交换两个整型变量的值 ...

  3. Decoration5:引入swagger2进行API管理

    这一部我们计划把swagger2引入到项目中,把网站的接口以文档的形式展示出来. 1.引入springfox-swagger2.springfox-swagger-ui 2.实现Swagger2 3. ...

  4. 源码分析:Java堆的创建

    虚拟机在内存中申请一片区域,由虚拟机自动管理,用来满足应用程序对象分配的空间需求,即堆空间. 由于程序运行的局部特性,程序创建的大多数对象都具有非常短的生命周期,而程序也会创建一些生命周期特别长的对象 ...

  5. 解决VisualStudio2013无法查看数组内容的问题

    症状: 在使用VS2013调试的时候,数组只能查看第一个元素的值.如图 解决方案: 调试>窗口>内存 输入数组的内存地址,右击内存窗口>带符号显示(也可以选择16进制显示,看你自己的 ...

  6. db2 连接报错connect。 ERRORCODE=-4499, SQLSTATE=08001(转载)

    在使用data studio连接远程DB2数据库时报错如下: [jcc][Thread:main][SQLException@5b775b77] java.sql.SQLException [jcc] ...

  7. 上传绕过WAF几种常见的姿势

    1:WTS-WAF 绕过上传原内容:Content-Disposition: form-data; name="up_picture"; filename="xss.ph ...

  8. Java反射机制的基本概念与使用

    本篇文章分为以下几个部分: 1.认识反射 2.反射的源头(Class类) 3.利用反射操作构造方法 4.利用反射调用类中的方法 5.反射中的invoke方法 6.利用反射调用类中的属性 反射在我们普通 ...

  9. 003Maven_Maven核心概念

    Maven核心概念 Maven插件 Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的每个插件都能实现多个功能,每个功能就是一个插件目标 Maven的生命周期与插件目标相互绑定,以 ...

  10. 考虑下面两个JSP文件代码片断: test1.jsp:

    <HTML> <BODY> <% pageContext.setAttribute(”ten”,new Integer(10));%> //1 </BODY& ...