您的位置:首页 > 其它

POI 导出Excel 并且根据内容设置列宽自适应

2016-11-10 00:13 447 查看
package com.XXX;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import com.eos.system.annotation.Bizlet;
import commonj.sdo.DataObject;

public class ExcelExportUtil {

/**
*
* Excel导出
* @author RangoLan
* @param criteriaEntity DataObject 获取填充数据源的查询对象
* @param fileName 生成的文件名前缀
* @param response HttpServletResponse响应
* @param colToProperty 表格列名和DataObject对象Property应的LinkedHashMap
* @param datePattern 日期格式数据格式
* @param HttpServletRequest request 请求对象,用于无数据输出时,内部跳转
* @param backPage 执行查询后无数据时返回画面
*/

@Bizlet("数据写入Excel并生成下载")
public static void exportExcel(String fileName,HttpServletRequest request,HttpServletResponse response,DataObject criteriaEntity,LinkedHashMap<String,String> colToProperty,String datePattern,String backPage) throws Exception {

//根据查询对象criteria填充数据源
DataObject[] datas = (DataObject[])com.eos.foundation.database.DatabaseUtil.queryEntitiesByCriteriaEntity("default", criteriaEntity);
if (datas != null && datas.length > 0) {

if(datePattern==null){
datePattern = "yyyy-MM-dd";
}

SXSSFWorkbook workbook = new SXSSFWorkbook(1000);

/** 设置格式* */
workbook.setCompressTempFiles(true);

// 表头样式
CellStyle headerStyle = workbook.createCellStyle();

//水平居中
headerStyle.setAlignment(CellStyle.ALIGN_CENTER);
//垂直居中
headerStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
//设置边框
headerStyle.setBorderTop(CellStyle.BORDER_THIN);
headerStyle.setBorderRight(CellStyle.BORDER_THIN);
headerStyle.setBorderBottom(CellStyle.BORDER_THIN);
headerStyle.setBorderLeft(CellStyle.BORDER_THIN);

//设置颜色
headerStyle.setFillForegroundColor(HSSFColor.LIGHT_GREEN.index);
headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

Font headerFont = workbook.createFont();
headerFont.setFontHeightInPoints((short) 12);
headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
headerStyle.setFont(headerFont);
// 单元格样式
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
//垂直居中
cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
//设置边框
cellStyle.setBorderTop(CellStyle.BORDER_THIN);
cellStyle.setBorderRight(CellStyle.BORDER_THIN);
cellStyle.setBorderBottom(CellStyle.BORDER_THIN);
cellStyle.setBorderLeft(CellStyle.BORDER_THIN);

//设置自动换行
cellStyle.setWrapText(true);

//设置字体
Font cellFont = workbook.createFont();
cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
cellStyle.setFont(cellFont);

//DataObject属性Property数组
String[] properties = new String[colToProperty.size()];
//表头数组
String[] headers = new String[colToProperty.size()];

int ii = 0;
for (Iterator<String> iter = colToProperty.keySet().iterator();iter.hasNext();) {
String fieldName = iter.next();

headers[ii] = fieldName;

properties[ii] = colToProperty.get(fieldName);

ii++;
}

// 遍历集合数据,产生数据行,填充Excel
int rowIndex = 0;
Sheet sheet = null;
for (DataObject data : datas) {

if (rowIndex == 65535 || rowIndex == 0) {

sheet = workbook.createSheet();// 如果数据超过了,则在第二页显示

Row headerRow = sheet.createRow(0);// 表头 rowIndex=0

for (int i = 0; i < headers.length; i++) {
headerRow.createCell(i).setCellValue(headers[i]);
//设置表头样式
headerRow.getCell(i).setCellStyle(headerStyle);

}

rowIndex = 1;// 数据内容从 rowIndex=1开始
}

//创建行
Row dataRow = sheet.createRow(rowIndex);

for (int i = 0; i < properties.length; i++) {
//创建单元格
Cell newCell = dataRow.createCell(i);

Object o = data.get(properties[i]);
String cellValue = "";
if (o == null) {//为空处理
cellValue = "";
} else if (o instanceof Date) {//日期格式化处理
cellValue = new SimpleDateFormat(datePattern).format(o);
} else {
cellValue = o.toString();
}
//单元格赋值
newCell.setCellValue(cellValue);
//单元格格式设置
newCell.setCellStyle(cellStyle);
}
rowIndex++;

}

OutputStream out = null;

//设置自动列宽

for (int i = 0; i < headers.length; i++) {
sheet.autoSizeColumn(i);
sheet.setColumnWidth(i,sheet.getColumnWidth(i)*17/10);
}

try {
out = response.getOutputStream();
fileName = fileName
+ "_"
+ new SimpleDateFormat("yyyyMMDDhh24mmssSSS")
.format(System.currentTimeMillis()) + ".xlsx";
response.setContentType("application/x-msdownload");
response.setHeader("Content-Disposition",
"attachment; filename="
+ URLEncoder.encode(fileName, "UTF-8"));
// 保存报表文件
workbook.write(out);
} catch (IOException e) {

e.printStackTrace();
} finally {
try {
if (out != null)
out.close();
response.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
}

}

} else {

// 无导出数据

request.setAttribute("noDataToExport", "没有数据可以导出!");
request.getRequestDispatcher(backPage).forward(request, response);

}

}


强调的是设置自适应列宽:sheet.autoSizeColumn(i);只这样设置是没有很好的效果的。所以采取了以下两步:

**1. sheet.autoSizeColumn(i);//先设置自动列宽

2. sheet.setColumnWidth(i,sheet.getColumnWidth(i)17/10);//设置列宽为自动列宽的1.7倍(当然不是严格的1.7倍,int的除法恕不再讨论),这个1.6左右也可以,这是本人测试的经验值*

经过本人测试,能够将excel的列宽很好的更具单元格的内容进行设置。

(PS:特别想说的是由于架构和项目需要,所以做成了这样,仅供参考。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息