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

来源:互联网 发布:nginx启用gzip压缩 编辑:程序博客网 时间:2024/06/11 17:09
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:特别想说的是由于架构和项目需要,所以做成了这样,仅供参考。)

1 0
原创粉丝点击