java实现把对象数组通过excel方式导出的功能
一、导入相关jar包,pom依赖如下:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>RELEASE</version>
</dependency>
二、开始撸代码
1.如果导出功能使用的比较多,可以将其做成一个工具类,对我下面贴出的代码进行改造
//结果返回的是写入的记录数(以下用的是自己业务场景数据)
public int downLoadToExcel(OutputStream outputStream,List<PaimaiMoneyVO> paimaiMoneyVOList) {
//文档对象
HSSFWorkbook wb = new HSSFWorkbook();
int rowNum = 0;
Sheet sheet = wb.createSheet("excel的标题");
Row row0 = sheet.createRow(rowNum++);
//因为场景不同,titil不同,可以在外面写成数组当参数传进来
row0.createCell(0).setCellValue("第一列属性名");
row0.createCell(1).setCellValue("第二列属性名");
row0.createCell(2).setCellValue("第三列属性名");
row0.createCell(3).setCellValue("第四列属性名");
row0.createCell(4).setCellValue("第五列属性名");
row0.createCell(5).setCellValue("第六列属性名");
if (paimaiMoneyVOList != null && paimaiMoneyVOList.size() > 0) {
for (PaimaiMoneyVO paimaiMoneyVO : paimaiMoneyVOList) {
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(paimaiMoneyVO.getPaimaiId());
row.createCell(1).setCellValue(paimaiMoneyVO.getTitle());
row.createCell(2).setCellValue(paimaiMoneyVO.getUsername());
row.createCell(3).setCellValue(paimaiMoneyVO.getMoney()+"元");
row.createCell(4).setCellValue("升价拍");
row.createCell(5).setCellValue(bidder);
}
}
try {
wb.write(outputStream);
LogEnum.LAW_WARE.info("表数据写入到excel表成功,一共写入了"+(rowNum - 1)+"条数据");
outputStream.close();
} catch (IOException e) {
LogEnum.LAW_WARE.error("流关闭异常!", e);
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
LogEnum.LAW_WARE.error("流关闭异常!", e);
}
}
}
return rowNum - 1;
}
2.“工具类”写好后,下面就开始使用它了,从上面的函数参数可以看到,我们需要传过去两个对象,一个是输出流OutPutStream,通过流的方式把excel想要到浏览器,
另外一个就是我们需要导出的对象数组,好了,不解释太多,看代码。(下面的方法写在action层,通过struts.xml配置访问即可实现下载)
public void exportBail(){
this.fileName = "excel文件名";
try {
List<PaimaiMoneyVO> paimaiMoneyVOList = new ArrayList<>();
//下面是我的业务场景获取对象数组
if(paimaiMoneySearchParam!=null){
paimaiMoneySearchParam.setVendorId(WebHelper.getVenderId());
paimaiMoneySearchParam.setPageSize(Constants.AUCTION_WARE_PAGE_SIZE);
paimaiMoneySearchParam.setPage(page);
PaimaiMoneyDto paimaiMoneyDto = auctionWareService1.searchPopPaimaiMoneyList(paimaiMoneySearchParam);
if(paimaiMoneyDto!=null){
int count = paimaiMoneyDto.getCount();
int totalPage = count/ Constants.AUCTION_WARE_PAGE_SIZE + (count% Constants.AUCTION_WARE_PAGE_SIZE > 0?1:0);
for(int i=1;i<=totalPage;i++){
paimaiMoneySearchParam.setPage(i);
PaimaiMoneyDto paimaiMoneyResultResult = auctionWareService1.searchPopPaimaiMoneyList(paimaiMoneySearchParam);
if(paimaiMoneyResultResult!=null){
paimaiMoneyVOList.addAll(paimaiMoneyResultResult.getList());
}
}
}
}
OutputStream outputStream = response.getOutputStream();
response.reset();//清空输出流
//下面是对中文文件名的处理
response.setCharacterEncoding("UTF-8");//设置相应内容的编码格式
//解析浏览器
final String userAgent = request.getHeader("USER-AGENT").toLowerCase();
if(userAgent.contains("firefox")){ //火狐浏览器
fileName = new String(fileName.getBytes(), "ISO8859-1");
}else{
fileName = URLEncoder.encode(fileName, "UTF-8"); //其他浏览器
fileName = fileName.Replace("+", "%20"); //encode后替换,解决空格问题(其中%20是空格在UTF-8下的编码 ,如果不这么写,浏览器会用+代替空格)
}
response.setHeader("Content-Disposition", "attachment;filename=" +fileName + ".xls");//指定输出文件名
response.setContentType("application/msexcel");//定义输出类型
int rouNum = ensurePriceListToExcel(outputStream,paimaiMoneyVOList);
LogEnum.LAW_WARE.info("【RiseAuctionAction.downLoadEnsurePriceExcel】导出成功,一共更新了{"+rouNum+"}条记录");
} catch (Exception e) {
LogEnum.LAW_WARE.error("【RiseAuctionAction.downLoadEnsurePriceExcel】导出失败,error is {}", e);
}
}
三、拓展(详细的工具类开发)
如果你觉得上面写的太简单了,可以继续往下看,我把它整理出了“万能”的工具类,供大家参考。
package com.jd.pop.auction.util.excel; import com.jd.common.web.result.Result;
import com.jd.pop.auction.util.excel.annotations.ExcelColumn;
import com.jd.pop.auction.util.excel.annotations.ExcelMapping;
import com.jd.pop.auction.util.excel.annotations.apt.ExcelColumnAPT;
import com.jd.pop.auction.util.excel.annotations.apt.ExcelMappingAPT;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress; import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List; public class GenerateExcel {
private final static Logger LOG = Logger.getLogger(GenerateExcel.class);
private HSSFWorkbook workbook; private HSSFCellStyle headStyle;
private HSSFFont headCellFont; private HSSFCellStyle theadStyle;
private HSSFFont theadCellFont; private HSSFCellStyle tbodyStyle;
private HSSFFont tbodyCellFont; private HSSFFont stringFont; private static final short COLUMN_WIDTH = 15;
private static final short ROW_HEIGHT = 400; public GenerateExcel() {
this.workbook = new HSSFWorkbook();
//标题
this.headStyle = workbook.createCellStyle();
headStyle.setFillForegroundColor(HSSFColor.GREY_50_PERCENT.index);
headStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
// headStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
// headStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
// headStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
// headStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
headStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // headStyle.setWrapText(true);
this.headCellFont = workbook.createFont();
headCellFont.setFontHeightInPoints((short)13);
headCellFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
headStyle.setFont(headCellFont); this.theadStyle = workbook.createCellStyle();
theadStyle.setFillForegroundColor(HSSFColor.WHITE.index);
theadStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
theadStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
theadStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
theadStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
theadStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
theadStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); theadCellFont = workbook.createFont();
theadCellFont.setColor(HSSFColor.BLACK.index);
theadCellFont.setFontHeightInPoints((short) 12);
theadCellFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); theadStyle.setFont(theadCellFont); tbodyStyle = workbook.createCellStyle();
tbodyStyle.setFillForegroundColor(HSSFColor.WHITE.index);
tbodyStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
tbodyStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
tbodyStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
tbodyStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
tbodyStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
tbodyStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
tbodyStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); tbodyCellFont = workbook.createFont();
tbodyCellFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
tbodyStyle.setFont(tbodyCellFont); stringFont = workbook.createFont();
stringFont.setColor(HSSFColor.BLACK.index);
} public <T> Result export(List<String> titles, Field[] fields, Class clazz, Collection<T> dataset, OutputStream out, boolean pager) {
Result result = new Result(false);
if(pager){ }else{
HSSFSheet sheet = workbook.createSheet( "第一页"); sheet.setDefaultColumnWidth(COLUMN_WIDTH);
sheet.setDefaultRowHeight(ROW_HEIGHT);
//标题
for (int i = 0; i <titles.size(); i++) {
HSSFRow titleRow = sheet.createRow(i);
titleRow.setHeightInPoints(20f);
sheet.addMergedRegion(new CellRangeAddress(i,i,0,fields.length-1));
HSSFCell titleCell =titleRow.createCell(0);
titleCell.setCellValue(titles.get(i));
titleCell.setCellStyle(headStyle);
} //列名
HSSFRow row = sheet.createRow(titles.size());
for (short i = 0; i < fields.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellStyle(theadStyle);
if(fields[i].isAnnotationPresent(ExcelColumn.class)){
ExcelColumn an_1 = fields[i].getAnnotation(ExcelColumn.class);
HSSFRichTextString text = new HSSFRichTextString(an_1.name());
cell.setCellValue(text);
}else if(fields[i].isAnnotationPresent(ExcelMapping.class)){
ExcelMapping an_1 = fields[i].getAnnotation(ExcelMapping.class);
HSSFRichTextString text = new HSSFRichTextString(an_1.name());
cell.setCellValue(text);
}
} Iterator<T> it = dataset.iterator();
int index = titles.size();
while (it.hasNext()) {
index++;
row = sheet.createRow(index);
T t = (T) it.next();
for (short i = 0; i < fields.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellStyle(tbodyStyle);
Field field = fields[i];
try {
String textValue;
if(field.isAnnotationPresent(ExcelMapping.class)){
textValue = new ExcelMappingAPT().getColumnValue(field,t,clazz);
}else{
textValue = new ExcelColumnAPT().getColumnValue(field,t,clazz);
}
cell.setCellValue(textValue);
} catch (NoSuchMethodException e) {
String errorMsg = field.getName() +"字段,第"+ index+ "条数据, NoSuchMethodException 反射错误!";
LOG.error(errorMsg,e);
result.addDefaultModel(errorMsg);
return result;
} catch (IllegalAccessException e) {
String errorMsg = field.getName() +"字段,第"+ index+ "条数据, IllegalAccessException ";
LOG.error(errorMsg,e);
result.addDefaultModel(errorMsg);
return result;
} catch (InvocationTargetException e) {
String errorMsg = field.getName() +"字段,第"+ index+ "条数据, InvocationTargetException ";
LOG.error(errorMsg,e);
result.addDefaultModel(errorMsg);
return result;
}
}
}
} try {
workbook.write(out);
result.setSuccess(true);
return result;
} catch (IOException e) {
String errorMsg = "将导出数据写入输出流失败!";
LOG.error("将导出数据写入输出流失败! ",e);
result.addDefaultModel(errorMsg);
return result;
}finally {
try {
out.close();
} catch (IOException e) {
String errorMsg = "关闭输出流异常!";
LOG.error("关闭输出流异常! ",e);
result.addDefaultModel(errorMsg);
return result;
}
}
} }
public class ExportExcelUtils {
private final static Logger LOG = Logger.getLogger(ExportExcelUtils.class);
public static <T> Result export(List<String> titles,List<T> sourceList, OutputStream out, boolean pager){
Result result = new Result(false);
if(CollectionUtils.isEmpty(sourceList)){
result.addDefaultModel("ExportExcelUtils's param sourceList is empty!");
LOG.error("ExportExcelUtils's param sourceList is empty!");
return result;
}
if( out == null){
LOG.error("ExportExcelUtils's param OutputStream is null!");
result.addDefaultModel("ExportExcelUtils's param OutputStream is null!");
return result;
}
Class clazz = null;
Field[] fieldArr = null;
try{
//得到需要转换的列名
clazz = sourceList.get(0).getClass();
Field[] fields = clazz.getDeclaredFields();
List<Field> fieldList = new ArrayList<Field>();
for(Field field:Arrays.asList(fields)){
field.setAccessible(true);
if(field.isAnnotationPresent(ExcelColumn.class)){
fieldList.add(field);
}else if(field.isAnnotationPresent(ExcelMapping.class)){
fieldList.add(field);
}
}
if(CollectionUtils.isEmpty(fieldList)){
LOG.error("实体类中无需要导出的字段!");
result.addDefaultModel("实体类中无需要导出的字段!");
return result;
}
fieldArr = fieldList.toArray(new Field[fieldList.size()]);
}catch(Exception e){
LOG.error("数据拼装异常!");
result.addDefaultModel("数据拼装异常!");
return result;
}
//生成excel
GenerateExcel ge = new GenerateExcel();
return ge.export(titles,fieldArr,clazz,sourceList,out,false);
} }
这一部分写的比较粗糙,但是实现的比较详细,仅供参考,大家可以稍微改造成为自己独有的utils,上面是实战,我们可以点这里看一下POI HSSF API组件的具体使用方法。
java实现把对象数组通过excel方式导出的功能的更多相关文章
- C++结构体对象数组的二进制方式读写
以一个学生信息的结构体数组为例. #include<iostream>#include<string>#include<fstream>using namespac ...
- JAVA学习一 对象数组
对象数组 今天在写一个代码,才发现自己对于对象数组的理解是不够的,那么就讲讲自己现在的理解. 对于数组中的每一个元素都是一个针对对象的引用 他会指向你的具体的一个堆上的对象,它本身知识一个地址值,与其 ...
- Java面向对象_对象数组
今天学习了对象数组,写点东西总结一下.废话不多说,啥是对象数组呢? 对象数组的概念是这么讲的,对象数组就是数组里的每个元素都是类的对象,赋值时先定义对象,然后将对象直接赋给数组. 举个例子,使用对象数 ...
- 【java】实例化对象的3种方式:new、clone、反射
实例化对象的3种方式:new.clone.反射
- Java中String对象两种赋值方式的区别
本文修改于:https://www.zhihu.com/question/29884421/answer/113785601 前言:在java中,String有两种赋值方式,第一种是通过“字面量”赋值 ...
- java虚拟机判断对象是否存活的方式
引用计数算法: 给对象添加一个引用计数器,每当有地方应用时,计数器值就加一,当引用失效时,程序计数器就减一,只要引用计数器的值为零时,就表示对象不可能再被引用,例如微软的 component ob ...
- java中产生对象的两种方式
/* * 普通new对象的过程! */ Person pp = new Person(); System.out.println(pp); /* * 利用代用参数的构造器产生对象实例! * 首先获得相 ...
- Java遍历Map对象的四种方式
关于java中遍历map具体哪四种方式,请看下文详解吧. 方式一 :这是最常见的并且在大多数情况下也是最可取的遍历方式.在键值都需要时使用. Map<Integer, Integer> m ...
- 【转】Java遍历Map对象的四种方式
关于java中遍历map具体哪四种方式,请看下文详解吧. 方式一 这是最常见的并且在大多数情况下也是最可取的遍历方式.在键值都需要时使用. Map<Integer, Integer> ma ...
随机推荐
- Linux 自动挂载硬盘的方法
每次重启后,都需要手动挂载硬盘( sudo mount ),非常不方便,使用一下步骤可以实现硬盘的自动挂载 第一步 获取硬盘的基本信息(UUID TYPE) sudo blkid 第二步 修改 / ...
- leveldb 学习记录(三) MemTable 与 Immutable Memtable
前文: leveldb 学习记录(一) skiplist leveldb 学习记录(二) Slice 存储格式: leveldb数据在内存中以 Memtable存储(核心结构是skiplist 已介绍 ...
- JS基础-分支结构-循环-数组
1.分支结构 1.if结构 语法: if(条件){ 语句块: } 注意: 1.条件尽量是boolean的,如果不是boolean的,以下条件值,会当做f ...
- 关于webconfig的记录恢复本
<?xml version="1.0"?> <!--注意: 除了手动编辑此文件以外,您还可以使用 Web 管理工具来配置应用程序的设置.可以使用 Visual S ...
- mui 页面提示:Unable to preventDefault inside passive
页面提示: 点击该事件:页面提示:[8mui.min.js:7 [Intervention] Unable to preventDefault inside passive event listene ...
- MySQL导入SQL语句报错 : MySQL server has gone away (已解决)
MySQL server has gone away 解决的方法其实很简单,我相信也有很多人遇到了这个问题.比如DZ论坛,安装好服务器,但是清空缓存等操作数据库的动作,运行时间稍长就会出现 MySQL ...
- EF6 学习笔记(五):数据库迁移及部署
EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 原文地址:Code First Migrations and Deployment 原文主要讲两部分:开发环境下 ...
- rabbitMq 初步
RabbitMQ的工作原理 它的基本结构 组成部分说明如下: Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue. Exchange:消息队列交换机,按一定的规则将消息路 ...
- javascript知识整理之this
js中的this是一个头疼的问题,尤其对于笔者这种初级的菜鸟来讲,下面梳理下this的知识,可以当做是初级进阶也好入门也罢,总归输出的才是自己掌握的: Js中this不是由词法作用域决定的 而是调用时 ...
- Servlet案例4:用户注册
数据库准备: CREATE DATABASE web; USE web; CREATE TABLE `user` ( `uid` ) NOT NULL, `username` ) DEFAULT NU ...