zoukankan      html  css  js  c++  java
  • displaytag的Excel导出实践

    本文转自 http://lingceng.iteye.com/blog/1820081/

    Displaytag官网有1.01.11.2等,注意找到对应的版本。源码和API可以在Maven库中找到。 
      常规的使用不是问题,这里说说关于Excel导出的问题,中文乱码,使用POI等。我使用的是Displaytag1.1。 

    基本导出功能 
      这种情况只需引入displaytag-1.1.jar。 
      设置column属性media="html"将不会导出,media="excel"不会页面显示,默认既显示又导出。 
      setProperty也可以写在displaytag.properties中应用于所有表格。 

    <display:table name="test" export="true" id="currentRowObject">  
      <display:column property="id" title="ID" />  
      <display:column property="email" />  
      <display:column property="status" />  
      <display:column media="html" property="date" />  
      <display:setProperty name="export.excel" value="true" />  
      <display:setProperty name="export.excel.filename" value="export.xls" />  
    </display:table>  

     这时候导出的excel打开的时候office会报警,但是能够打开,因为这不是正真的excel,只是csv改了后缀的纯文本格式。可能出现中文乱码,通过重载ExcelView来解决。 

    Class SimpleChineseExcelView extends ExcelView {  
      public String getMimeType(){  
        //原代码是return "application/vnd.ms-excel";  
        return "application/vnd.ms-excel;charset=gbk";   
      }  
    }  

    修改displaytag.properties中对应条目: 
      export.excel.class=yourpackage.SimpleChineseExcelView 
      
      这样就勉强能用了,只要能够忍受每次都需要另存为excel来避免报警,不用中文文件名,不在bodycontent中使用中文。这样的实现只能是差强人意。中文问题解决 

    使用POI 
      需要引入额外的displaytag-export-excel-1.1.jar,使用Maven解决依赖。 
      修改displaytag.properties中对应条目: 
      export.excel.class=org.displaytag.export.excel.ExcelHssfView 
      配置export filter: 

    <!--Configure the Filter in your web.xml:-->  
      <filter>  
        <filter-name>ResponseOverrideFilter</filter-name>  
        <filter-class>org.displaytag.filter.ResponseOverrideFilter</filter-class>  
      </filter>  
    <!--And add mappings for urls the filter will intercept, for example:-->  
      <filter-mapping>  
        <filter-name>ResponseOverrideFilter</filter-name>  
        <url-pattern>*.do</url-pattern>  
      </filter-mapping>  
      <filter-mapping>  
        <filter-name>ResponseOverrideFilter</filter-name>  
        <url-pattern>*.jsp</url-pattern>  
      </filter-mapping>  

     filter-mapping加在struts之前,acegi之后(如果有),放struts之后会出问题。 
      很好地解决各种中文问题,也是真正的excel。 

      实践Hack: 
      项目中已经有了poi3.6,而displaytag-export-excel-1.1依赖的是poi3.0,版本太高,需要重新写一个ExcelHssfView。其实很简单,找到ExcelHssfView的源码,删除其中的所有的setEncoding方法,setEncoding方法在poi3.6中没有。修改后的代码如下,当然记得修改export.excel.class: 

    package com.lingceng;  
      
    import java.io.OutputStream;  
    import java.util.Calendar;  
    import java.util.Date;  
    import java.util.Iterator;  
      
    import javax.servlet.jsp.JspException;  
      
    import org.apache.commons.lang.ObjectUtils;  
    import org.apache.commons.lang.StringEscapeUtils;  
    import org.apache.commons.lang.StringUtils;  
    import org.apache.poi.hssf.usermodel.HSSFCell;  
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;  
    import org.apache.poi.hssf.usermodel.HSSFFont;  
    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.displaytag.Messages;  
    import org.displaytag.exception.BaseNestableJspTagException;  
    import org.displaytag.exception.SeverityEnum;  
    import org.displaytag.export.BinaryExportView;  
    import org.displaytag.model.Column;  
    import org.displaytag.model.ColumnIterator;  
    import org.displaytag.model.HeaderCell;  
    import org.displaytag.model.Row;  
    import org.displaytag.model.RowIterator;  
    import org.displaytag.model.TableModel;  
      
      
    /** 
     * Excel exporter using POI HSSF. 
     * @author Fabrizio Giustina 
     * @author rapruitt 
     * @version $Revision: 1.2 $ ($Author: fgiust $) 
     */  
    public class MyExcelHssfView implements BinaryExportView  
    {  
      
        /** 
         * TableModel to render. 
         */  
        private TableModel model;  
      
        /** 
         * export full list? 
         */  
        private boolean exportFull;  
      
        /** 
         * include header in export? 
         */  
        private boolean header;  
      
        /** 
         * decorate export? 
         */  
        private boolean decorated;  
      
        /** 
         * Generated sheet. 
         */  
        private HSSFSheet sheet;  
      
        /** 
         * @see org.displaytag.export.ExportView#setParameters(TableModel, boolean, boolean, boolean) 
         */  
        public void setParameters(TableModel tableModel, boolean exportFullList, boolean includeHeader,  
            boolean decorateValues)  
        {  
            this.model = tableModel;  
            this.exportFull = exportFullList;  
            this.header = includeHeader;  
            this.decorated = decorateValues;  
        }  
      
        /** 
         * @return "application/vnd.ms-excel" 
         * @see org.displaytag.export.BaseExportView#getMimeType() 
         */  
        public String getMimeType()  
        {  
            return "application/vnd.ms-excel"; //$NON-NLS-1$  
        }  
      
        /** 
         * @see org.displaytag.export.BinaryExportView#doExport(OutputStream) 
         */  
        public void doExport(OutputStream out) throws JspException  
        {  
            try  
            {  
                HSSFWorkbook wb = new HSSFWorkbook();  
                sheet = wb.createSheet("-");  
      
                int rowNum = 0;  
                int colNum = 0;  
      
                if (this.header)  
                {  
                    // Create an header row  
                    HSSFRow xlsRow = sheet.createRow(rowNum++);  
      
                    HSSFCellStyle headerStyle = wb.createCellStyle();  
                    headerStyle.setFillPattern(HSSFCellStyle.FINE_DOTS);  
                    headerStyle.setFillBackgroundColor(HSSFColor.BLUE_GREY.index);  
                    HSSFFont bold = wb.createFont();  
                    bold.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);  
                    bold.setColor(HSSFColor.WHITE.index);  
                    headerStyle.setFont(bold);  
      
                    Iterator iterator = this.model.getHeaderCellList().iterator();  
      
                    while (iterator.hasNext())  
                    {  
                        HeaderCell headerCell = (HeaderCell) iterator.next();  
      
                        String columnHeader = headerCell.getTitle();  
      
                        if (columnHeader == null)  
                        {  
                            columnHeader = StringUtils.capitalize(headerCell.getBeanPropertyName());  
                        }  
      
                        HSSFCell cell = xlsRow.createCell((short) colNum++);  
                        cell.setCellValue(columnHeader);  
                        cell.setCellStyle(headerStyle);  
                        //cell.setEncoding(HSSFCell.ENCODING_UTF_16);  
                    }  
                }  
      
                // get the correct iterator (full or partial list according to the exportFull field)  
                RowIterator rowIterator = this.model.getRowIterator(this.exportFull);  
                // iterator on rows  
      
                while (rowIterator.hasNext())  
                {  
                    Row row = rowIterator.next();  
                    HSSFRow xlsRow = sheet.createRow(rowNum++);  
                    colNum = 0;  
      
                    // iterator on columns  
                    ColumnIterator columnIterator = row.getColumnIterator(this.model.getHeaderCellList());  
      
                    while (columnIterator.hasNext())  
                    {  
                        Column column = columnIterator.nextColumn();  
      
                        // Get the value to be displayed for the column  
                        Object value = column.getValue(this.decorated);  
      
                        HSSFCell cell = xlsRow.createCell((short) colNum++);  
                        //cell.setEncoding(HSSFCell.ENCODING_UTF_16);  
      
                        if (value instanceof Number)  
                        {  
                            Number num = (Number) value;  
                            cell.setCellValue(num.doubleValue());  
                        }  
                        else if (value instanceof Date)  
                        {  
                            cell.setCellValue((Date) value);  
                        }  
                        else if (value instanceof Calendar)  
                        {  
                            cell.setCellValue((Calendar) value);  
                        }  
                        else  
                        {  
                            cell.setCellValue(escapeColumnValue(value));  
                        }  
      
                    }  
                }  
                wb.write(out);  
            }  
            catch (Exception e)  
            {  
                throw new ExcelGenerationException(e);  
            }  
        }  
      
        // patch from Karsten Voges  
        /** 
         * Escape certain values that are not permitted in excel cells. 
         * @param rawValue the object value 
         * @return the escaped value 
         */  
        protected String escapeColumnValue(Object rawValue)  
        {  
            if (rawValue == null)  
            {  
                return null;  
            }  
            String returnString = ObjectUtils.toString(rawValue);  
            // escape the String to get the tabs, returns, newline explicit as 	 
     
      
            returnString = StringEscapeUtils.escapeJava(StringUtils.trimToEmpty(returnString));  
            // remove tabs, insert four whitespaces instead  
            returnString = StringUtils.replace(StringUtils.trim(returnString), "\t", "    ");  
            // remove the return, only newline valid in excel  
            returnString = StringUtils.replace(StringUtils.trim(returnString), "\r", " ");  
            // unescape so that 
     gets back to newline  
            returnString = StringEscapeUtils.unescapeJava(returnString);  
            return returnString;  
        }  
      
        /** 
         * Wraps IText-generated exceptions. 
         * @author Fabrizio Giustina 
         * @version $Revision: 1.2 $ ($Author: fgiust $) 
         */  
        static class ExcelGenerationException extends BaseNestableJspTagException  
        {  
      
            /** 
             * D1597A17A6. 
             */  
            private static final long serialVersionUID = 899149338534L;  
      
            /** 
             * Instantiate a new PdfGenerationException with a fixed message and the given cause. 
             * @param cause Previous exception 
             */  
            public ExcelGenerationException(Throwable cause)  
            {  
                super(ExcelHssfView.class, Messages.getString("ExcelView.errorexporting"), cause); //$NON-NLS-1$  
            }  
      
            /** 
             * @see org.displaytag.exception.BaseNestableJspTagException#getSeverity() 
             */  
            public SeverityEnum getSeverity()  
            {  
                return SeverityEnum.ERROR;  
            }  
        }  
      
    }  
  • 相关阅读:
    Luogu P4727-- 【HNOI2009】图的同构记数
    UOJ #390. 【UNR #3】百鸽笼
    Loj #2541「PKUWC2018」猎人杀
    BZOJ 1444:[JSOI2009]有趣的游戏
    CF895C: Square Subsets && 【BZOJ2844】albus就是要第一个出场
    [NOI2011]阿狸的打字机
    不要再搜啦,满足你的需要,封装保留小数点后两位
    react 中刷新,路由传参数丢失不存在了?
    字符串根据某个符号查找并截取
    react-swiper 如何实现滑动小卡片的移动?
  • 原文地址:https://www.cnblogs.com/520playboy/p/6348031.html
Copyright © 2011-2022 走看看