步骤一、自定义注解

步骤二、写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. unity, standard shader消耗两个draw call

    假设场景中只放一个球,关掉阴影和skybox,球体使用Unlit/Texture shader,则draw call数为2(背景占一个draw call,球占一个draw call). 相同情况下若将 ...

  2. Spring Cloud(五):熔断监控Hystrix Dashboard和Turbine

    Hystrix-dashboard是一款针对Hystrix进行实时监控的工具,通过Hystrix Dashboard我们可以在直观地看到各Hystrix Command的请求响应时间, 请求成功率等数 ...

  3. AESDK关于AEFX_CLR_STRUCT的用处

    主要是在初始化UI值的时候遇到问题,一直报错 但确实没有用到ui_width,ui_height...,仔细检查例子工程发现,少了一个AEFX_CLR_STRUCT宏 AEFX_CLR_STRUCT其 ...

  4. 集合运算 蓝桥杯 set容器

    题目描述 给出两个整数集合A.B,求出他们的交集.并集以及B在A中的余集. 输入格式 第一行为一个整数n,表示集合A中的元素个数. 第二行有n个互不相同的用空格隔开的整数,表示集合A中的元素. 第三行 ...

  5. js 实现依赖注入的思想,后端框架思想搬到前端来

    前述:咱们写一些页面的时候,很多需要用ajax来实现,显示又有很多表单提交的add或者update操作,太烦了,能不能有什么方法能够简单些呢? 说实话我都是被公司给逼的 应用场景: 前后端一一对应.表 ...

  6. centOS7 配置DNS上外网

    CentOS7 linux下DNS的永久性添加 I.网上很多讲的dns的永久性添加其实都是暂时性添加,重启网卡后就会丢失.代码如下: echo nameserver 8.8.8.8 > /etc ...

  7. jquery 情况form表单的所有内容

    #project_file_upload 为表单的id $(':input','#project_file_upload') .not(':button, :submit, :reset, :hidd ...

  8. RIP动态路由的配置

    RIP其实相对比会比静态路由会简单的多,只需要使用rip命令添加邻居的网络号即可. 命令: Router(config)#ip route rip Router(config-router)#netw ...

  9. am335x alsa codec调试

    root@phyCORE-AM335x:~ aplay -l**** List of PLAYBACK Hardware Devices ****card 0: audio [PCM051 audio ...

  10. 虚拟化–操作系统级 LXC Linux Containers内核轻量级虚拟化技术

    友情提示:非原文链接可能会影响您的阅读体验,欢迎查看原文.(http://blog.geekcome.com) 原文地址:http://blog.geekcome.com/archives/288 软 ...