java實(shí)現(xiàn)把對象數(shù)組通過excel方式導(dǎo)出的功能
一、導(dǎo)入相關(guān)jar包,pom依賴如下:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>RELEASE</version> </dependency>
二、開始擼代碼
1.如果導(dǎo)出功能使用的比較多,可以將其做成一個(gè)工具類,對我下面貼出的代碼進(jìn)行改造
//結(jié)果返回的是寫入的記錄數(shù)(以下用的是自己業(yè)務(wù)場景數(shù)據(jù))
public int downLoadToExcel(OutputStream outputStream,List<PaimaiMoneyVO> paimaiMoneyVOList) {
//文檔對象
HSSFWorkbook wb = new HSSFWorkbook();
int rowNum = 0;
Sheet sheet = wb.createSheet("excel的標(biāo)題");
Row row0 = sheet.createRow(rowNum++);
//因?yàn)閳鼍安煌瑃itil不同,可以在外面寫成數(shù)組當(dāng)參數(shù)傳進(jìn)來
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("升價(jià)拍");
row.createCell(5).setCellValue(bidder);
}
}
try {
wb.write(outputStream);
LogEnum.LAW_WARE.info("表數(shù)據(jù)寫入到excel表成功,一共寫入了"+(rowNum - 1)+"條數(shù)據(jù)");
outputStream.close();
} catch (IOException e) {
LogEnum.LAW_WARE.error("流關(guān)閉異常!", e);
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
LogEnum.LAW_WARE.error("流關(guān)閉異常!", e);
}
}
}
return rowNum - 1;
}
2.“工具類”寫好后,下面就開始使用它了,從上面的函數(shù)參數(shù)可以看到,我們需要傳過去兩個(gè)對象,一個(gè)是輸出流OutPutStream,通過流的方式把excel想要到瀏覽器,
另外一個(gè)就是我們需要導(dǎo)出的對象數(shù)組,好了,不解釋太多,看代碼。(下面的方法寫在action層,通過struts.xml配置訪問即可實(shí)現(xiàn)下載)
public void exportBail(){
this.fileName = "excel文件名";
try {
List<PaimaiMoneyVO> paimaiMoneyVOList = new ArrayList<>();
//下面是我的業(yè)務(wù)場景獲取對象數(shù)組
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");//設(shè)置相應(yīng)內(nèi)容的編碼格式
//解析瀏覽器
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下的編碼 ,如果不這么寫,瀏覽器會(huì)用+代替空格)
}
response.setHeader("Content-Disposition", "attachment;filename=" +fileName + ".xls");//指定輸出文件名
response.setContentType("application/msexcel");//定義輸出類型
int rouNum = ensurePriceListToExcel(outputStream,paimaiMoneyVOList);
LogEnum.LAW_WARE.info("【RiseAuctionAction.downLoadEnsurePriceExcel】導(dǎo)出成功,一共更新了{(lán)"+rouNum+"}條記錄");
} catch (Exception e) {
LogEnum.LAW_WARE.error("【RiseAuctionAction.downLoadEnsurePriceExcel】導(dǎo)出失敗,error is {}", e);
}
}
三、拓展(詳細(xì)的工具類開發(fā))
如果你覺得上面寫的太簡單了,可以繼續(xù)往下看,我把它整理出了“萬能”的工具類,供大家參考。
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();
//標(biāo)題
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);
//標(biāo)題
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+ "條數(shù)據(jù), NoSuchMethodException 反射錯(cuò)誤!";
LOG.error(errorMsg,e);
result.addDefaultModel(errorMsg);
return result;
} catch (IllegalAccessException e) {
String errorMsg = field.getName() +"字段,第"+ index+ "條數(shù)據(jù), IllegalAccessException ";
LOG.error(errorMsg,e);
result.addDefaultModel(errorMsg);
return result;
} catch (InvocationTargetException e) {
String errorMsg = field.getName() +"字段,第"+ index+ "條數(shù)據(jù), InvocationTargetException ";
LOG.error(errorMsg,e);
result.addDefaultModel(errorMsg);
return result;
}
}
}
}
try {
workbook.write(out);
result.setSuccess(true);
return result;
} catch (IOException e) {
String errorMsg = "將導(dǎo)出數(shù)據(jù)寫入輸出流失敗!";
LOG.error("將導(dǎo)出數(shù)據(jù)寫入輸出流失?。?",e);
result.addDefaultModel(errorMsg);
return result;
}finally {
try {
out.close();
} catch (IOException e) {
String errorMsg = "關(guān)閉輸出流異常!";
LOG.error("關(guān)閉輸出流異常! ",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{
//得到需要轉(zhuǎn)換的列名
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("實(shí)體類中無需要導(dǎo)出的字段!");
result.addDefaultModel("實(shí)體類中無需要導(dǎo)出的字段!");
return result;
}
fieldArr = fieldList.toArray(new Field[fieldList.size()]);
}catch(Exception e){
LOG.error("數(shù)據(jù)拼裝異常!");
result.addDefaultModel("數(shù)據(jù)拼裝異常!");
return result;
}
//生成excel
GenerateExcel ge = new GenerateExcel();
return ge.export(titles,fieldArr,clazz,sourceList,out,false);
}
}
這一部分寫的比較粗糙,但是實(shí)現(xiàn)的比較詳細(xì),僅供參考,大家可以稍微改造成為自己獨(dú)有的utils。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
springmvc配置線程池Executor做多線程并發(fā)操作的代碼實(shí)例
今天小編就為大家分享一篇關(guān)于springmvc配置線程池Executor做多線程并發(fā)操作的代碼實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-03-03
SpringBoot應(yīng)用能直接運(yùn)行java -jar的原因分析
這篇文章主要介紹了SpringBoot應(yīng)用為什么能直接運(yùn)行java -jar,首先明確一點(diǎn),普通jar包是不能直接運(yùn)行的,比如工具類jar,要能運(yùn)行,至少得要一個(gè)main函數(shù)作為入口吧?本文給大家介紹了詳細(xì)的原因分析,需要的朋友可以參考下2024-03-03
Maven項(xiàng)目中resources配置總結(jié)
這篇文章主要介紹了Maven項(xiàng)目中resources配置總結(jié),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
Java微信公眾平臺開發(fā)(2) 微信服務(wù)器post消息體的接收
這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺開發(fā)第二步,微信服務(wù)器post消息體的接收,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
javaweb實(shí)戰(zhàn)之商城項(xiàng)目開發(fā)(二)
這篇文章主要針對javaweb商城項(xiàng)目開發(fā)進(jìn)行實(shí)戰(zhàn)演習(xí),利用mybatis創(chuàng)建DAO層,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-02-02
Java實(shí)現(xiàn)在不同線程中運(yùn)行的代碼實(shí)例
這篇文章主要介紹了Java實(shí)現(xiàn)在不同線程中運(yùn)行的代碼,結(jié)合具體實(shí)例形式分析了java多線程操作的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-04-04
解析Flink內(nèi)核原理與實(shí)現(xiàn)核心抽象
Flink API提供了開發(fā)的接口,此外,為了實(shí)現(xiàn)業(yè)務(wù)邏輯,還必須為開發(fā)者提供自定義業(yè)務(wù)邏輯的能力,下面為大家解析Flink內(nèi)核原理與實(shí)現(xiàn)核心抽象2021-08-08

