zoukankan      html  css  js  c++  java
  • OpenReports中文支持方案

    此文章在《OpenReports中文支持完全解决方案.doc》的基础上做优化,并贴出代码。已测试通过。

    一、主要解决的问题                    

    1 页面显示支持中文

    2 与服务器或数据库的交互支持中文

    3 查询结果支持中文

    4 导出文件名及内容支持中文

    二、解决方案及方法

    1 增加的类

    1.1 cn.ExportDelegate

      直接来自原文件org.displaytag.filter.ExportDelegate,只是将文件名转码,

    解决中文表格数据和导出中文文件名时,会产生乱码现象。被cn.ResponseOverrideFilter调用。

    package cn;
    
    
    /**
     * Licensed under the Artistic License; you may not use this file
     * except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://displaytag.sourceforge.net/license.html
     *
     * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
     * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
     * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     */
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.util.Map;
    
    import javax.servlet.ServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.lang.StringUtils;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.displaytag.filter.BufferedResponseWrapper;
    import org.displaytag.tags.TableTag;
    import org.displaytag.tags.TableTagParameters;
    
    
    /**
     * Actually writes out the content of the wrapped response. Used by the j2ee filter and the Spring interceptor
     * implementations.
     * @author Fabrizio Giustina
     * @version $Revision: 1081 $ ($Author: fgiust $)
     */
    public final class ExportDelegate
    {
    
        /**
         * logger.
         */
        private static Log log = LogFactory.getLog(ExportDelegate.class);
    
        /**
         * Don?t instantiate.
         */
        private ExportDelegate()
        {
            // unused
        }
    
        /**
         * Actually writes exported data. Extracts content from the Map stored in request with the
         * <code>TableTag.FILTER_CONTENT_OVERRIDE_BODY</code> key.
         * @param wrapper BufferedResponseWrapper implementation
         * @param response HttpServletResponse
         * @param request ServletRequest
         * @throws IOException exception thrown by response writer/outputStream
         */
        protected static void writeExport(HttpServletResponse response, ServletRequest request,
            BufferedResponseWrapper wrapper) throws IOException
        {
    
            if (wrapper.isOutRequested())
            {
                // data already written
                log.debug("Filter operating in unbuffered mode. Everything done, exiting");
                return;
            }
    
            // if you reach this point the PARAMETER_EXPORTING has been found, but the special header has never been set in
            // response (this is the signal from table tag that it is going to write exported data)
            log.debug("Filter operating in buffered mode. ");
    
            Map bean = (Map) request.getAttribute(TableTag.FILTER_CONTENT_OVERRIDE_BODY);
    
            if (log.isDebugEnabled())
            {
                log.debug(bean);
            }
    
            Object pageContent = bean.get(TableTagParameters.BEAN_BODY);
    
            if (pageContent == null)
            {
                if (log.isDebugEnabled())
                {
                    log.debug("Filter is enabled but exported content has not been found. Maybe an error occurred?");
                }
    
                response.setContentType(wrapper.getContentType());
                PrintWriter out = response.getWriter();
    
                out.write(wrapper.getContentAsString());
                out.flush();
                return;
            }
    
            // clear headers
            if (!response.isCommitted())
            {
                response.reset();
            }
    
            String filename = (String) bean.get(TableTagParameters.BEAN_FILENAME);
            String contentType = (String) bean.get(TableTagParameters.BEAN_CONTENTTYPE);
    
            if (StringUtils.isNotBlank(filename))
            {
    //            response.setHeader("Content-Disposition", "attachment; filename="" + filename + """);
                String filename1 = new String(filename.getBytes("GBK"),("ISO8859-1"));
                response.setHeader("Content-Disposition", "attachment; filename="" + filename1 + """);
            }
    
            String characterEncoding = wrapper.getCharacterEncoding();
            String wrappedContentType = wrapper.getContentType();
    
            if (wrappedContentType != null && wrappedContentType.indexOf("charset") > -1)
            {
                // charset is already specified (see #921811)
                characterEncoding = StringUtils.substringAfter(wrappedContentType, "charset=");
            }
    
            if (characterEncoding != null && contentType.indexOf("charset") == -1) //$NON-NLS-1$
            {
                contentType += "; charset=" + characterEncoding; //$NON-NLS-1$
            }
    
            response.setContentType(contentType);
    
            if (pageContent instanceof String)
            {
                // text content
                if (characterEncoding != null)
                {
                    response.setContentLength(((String) pageContent).getBytes(characterEncoding).length);
                }
                else
                {
                    response.setContentLength(((String) pageContent).getBytes().length);
                }
    
                PrintWriter out = response.getWriter();
                out.write((String) pageContent);
                out.flush();
            }
            else
            {
                // dealing with binary content
                byte[] content = (byte[]) pageContent;
                response.setContentLength(content.length);
                OutputStream out = response.getOutputStream();
                out.write(content);
                out.flush();
            }
        }
    }

    1.2 cn.ResponseOverrideFilter

      直接来自原文件org.displaytag.filter.ResponseOverrideFilter,原有ResponseOverrideFilter路径指向新建Filter的路径,必须。

    package cn;
    
    //=============
    /**
     * Licensed under the Artistic License; you may not use this file
     * except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://displaytag.sourceforge.net/license.html
     *
     * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
     * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
     * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     */
    
    
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.lang.StringUtils;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.displaytag.Messages;
    import org.displaytag.filter.BufferedResponseWrapper;
    import org.displaytag.filter.BufferedResponseWrapper13Impl;
    import org.displaytag.tags.TableTag;
    import org.displaytag.tags.TableTagParameters;
    
    
    /**
     * <p>
     * Allow the author of an included JSP page to reset the content type to something else (like a binary stream), and then
     * write the new info back as the exclusive response, clearing the buffers of all previously added content.
     * </p>
     * <p>
     * This filter allows TableTag users to perform exports from pages that are run as includes, such as from Struts or a
     * jsp:include. If that is your intention, just add this Filter to your web.xml and map it to the appropriate requests,
     * using something like:
     * </p>
     * 
     * <pre>
     *  &lt;filter>
     *      &lt;filter-name>ResponseOverrideFilter&lt;/filter-name>
     *      &lt;filter-class>org.displaytag.filter.ResponseOverrideFilter&lt;/filter-class>
     *  &lt;/filter>
     *  &lt;filter-mapping>
     *      &lt;filter-name>ResponseOverrideFilter&lt;/filter-name>
     *      &lt;url-pattern>*.do&lt;/url-pattern>
     *  &lt;/filter-mapping>
     *  &lt;filter-mapping>
     *      &lt;filter-name>ResponseOverrideFilter&lt;/filter-name>
     *      &lt;url-pattern>*.jsp&lt;/url-pattern>
     *  &lt;/filter-mapping>
     * </pre>
     * 
     * <p>
     * By default the filter buffers all the export content before writing it out. You can set an optional parameter
     * <code>buffer</code> to <code>false</code> to make the filter write directly to the output stream. This could be
     * faster and uses less memory, but the content length will not be set.
     * </p>
     * 
     * <pre>
     *  &lt;filter>
     *      &lt;filter-name>ResponseOverrideFilter&lt;/filter-name>
     *      &lt;filter-class>org.displaytag.filter.ResponseOverrideFilter&lt;/filter-class>
     *      &lt;init-param>
     *          &lt;param-name>buffer&lt;/param-name>
     *          &lt;param-value>false&lt;/param-value>
     *      &lt;/init-param>
     *  &lt;/filter>
     *  </pre>
     * 
     * @author rapruitt
     * @author Fabrizio Giustina
     * @version $Revision: 1081 $ ($Author: fgiust $)
     */
    public class ResponseOverrideFilter implements Filter
    {
    
        /**
         * Logger.
         */
        private Log log;
    
        /**
         * Force response buffering. Enabled by default.
         */
        private boolean buffer = true;
    
        /**
         * {@inheritDoc}
         */
        public void init(FilterConfig filterConfig)
        {
            log = LogFactory.getLog(ResponseOverrideFilter.class);
            String bufferParam = filterConfig.getInitParameter("buffer");
            if (log.isDebugEnabled())
            {
                log.debug("bufferParam=" + bufferParam);
            }
            buffer = bufferParam == null || StringUtils.equalsIgnoreCase("true", bufferParam);
    
            log.info("Filter initialized. Response buffering is " + (buffer ? "enabled" : "disabled"));
        }
    
        /**
         * {@inheritDoc}
         */
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException
        {
            
            if (servletRequest.getParameter(TableTagParameters.PARAMETER_EXPORTING) == null)
            {
                if (log.isDebugEnabled())
                {
                    log.debug(Messages.getString("ResponseOverrideFilter.parameternotfound")); //$NON-NLS-1$
                }
                // don't filter!
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
    
            HttpServletRequest request = (HttpServletRequest) servletRequest;
    
            BufferedResponseWrapper wrapper = new BufferedResponseWrapper13Impl((HttpServletResponse) servletResponse);
    
            Map contentBean = new HashMap(4);
            if (buffer)
            {
                contentBean.put(TableTagParameters.BEAN_BUFFER, Boolean.TRUE);
            }
            request.setAttribute(TableTag.FILTER_CONTENT_OVERRIDE_BODY, contentBean);
    //        request.setAttribute("cn.ResponseOverrideFilter", contentBean);
    
            filterChain.doFilter(request, wrapper);
    
            ExportDelegate.writeExport((HttpServletResponse) servletResponse, servletRequest, wrapper);
        }
    
        /**
         * {@inheritDoc}
         */
        public void destroy()
        {
            // nothing to destroy
        }
    }

    1.3 cn.SetCharacterEncodingFilter

      是一个标准的自定义字符集转换Filter,必须。

      

    package cn;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class SetCharacterEncodingFilter implements Filter {
         /**
         * The default character encoding to set for requests that pass through
         * this filter.
         */
        protected String encoding = null;
     
        /**
         * The filter configuration object we are associated with.  If this value
         * is null, this filter instance is not currently configured.
         */
        protected FilterConfig filterConfig = null;
     
        /**
         * Should a character encoding specified by the client be ignored?
         */
        protected boolean ignore = true;
     
        public void destroy() {
            this.encoding = null;
            this.filterConfig = null;
        }
     
        public void doFilter(ServletRequest request, ServletResponse response,
                             FilterChain chain) throws IOException, ServletException {
     
            // Conditionally select and set the character encoding to be used
            if (ignore || (request.getCharacterEncoding() == null)) {
                String encoding = selectEncoding(request);
                if (encoding != null)
                    request.setCharacterEncoding(encoding);
            }
     
            chain.doFilter(request, response);
     
        }
     
        /**
         * Place this filter into service.
         * @param filterConfig The filter configuration object
         */
        public void init(FilterConfig filterConfig) throws ServletException {
     
            this.filterConfig = filterConfig;
            this.encoding = filterConfig.getInitParameter("encoding");
            String value = filterConfig.getInitParameter("ignore");
            if (value == null)
                this.ignore = true;
            else if (value.equalsIgnoreCase("true"))
                this.ignore = true;
            else if (value.equalsIgnoreCase("yes"))
                this.ignore = true;
            else
                this.ignore = false;
     
        }
     
        protected String selectEncoding(ServletRequest request) {
            return (this.encoding);
        }
        
    }

    1.4 org.displaytag.export.PdfView

      

    /**
     * Licensed under the Artistic License; you may not use this file
     * except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://displaytag.sourceforge.net/license.html
     *
     * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
     * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
     * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     */
    package org.displaytag.export;
    
    import java.io.OutputStream;
    import java.util.Iterator;
    
    import javax.servlet.jsp.JspException;
    
    import org.apache.commons.lang.ObjectUtils;
    import org.apache.commons.lang.StringUtils;
    import org.displaytag.Messages;
    import org.displaytag.exception.BaseNestableJspTagException;
    import org.displaytag.exception.SeverityEnum;
    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;
    import org.displaytag.util.TagConstants;
    
    import com.lowagie.text.BadElementException;
    import com.lowagie.text.Cell;
    import com.lowagie.text.Chunk;
    import com.lowagie.text.Document;
    import com.lowagie.text.Element;
    import com.lowagie.text.Font;
    import com.lowagie.text.FontFactory;
    import com.lowagie.text.HeaderFooter;
    import com.lowagie.text.PageSize;
    import com.lowagie.text.Phrase;
    import com.lowagie.text.Rectangle;
    import com.lowagie.text.Table;
    import com.lowagie.text.pdf.PdfWriter;
    
    
    /**
     * PDF exporter using IText. This class is provided more as an example than as a "production ready" class: users
     * probably will need to write a custom export class with a specific layout.
     * @author Ivan Markov
     * @author Fabrizio Giustina
     * @version $Revision: 1081 $ ($Author: fgiust $)
     */
    public class PdfView implements BinaryExportView
    {
    
        private TableModel model;
        private boolean exportFull;
        private boolean header;
        private boolean decorated;
        private Table tablePDF;
        private Font smallFont;
        
        public void setParameters(TableModel tableModel, boolean exportFullList, boolean includeHeader,
            boolean decorateValues)
        {
            this.model = tableModel;
            this.exportFull = exportFullList;
            this.header = includeHeader;
            this.decorated = decorateValues;
        }
    
        protected void initTable() throws BadElementException
        {
           this.tablePDF = new Table(this.model.getNumberOfColumns());
           this.tablePDF.getDefaultCell().setVerticalAlignment(4);
           this.tablePDF.setCellsFitPage(true);
           this.tablePDF.setWidth(100.0F);
           this.tablePDF.setPadding(2.0F);
           this.tablePDF.setSpacing(0.0F);
    
    //        smallFont = FontFactory.getFont(FontFactory.HELVETICA, 7, Font.NORMAL, new Color(0, 0, 0));
           //Font name:宋体(中文字体) PDF Font name:STSong-Light PDF Encoding:UniGB-UCS2-H(简体中文)
            smallFont = FontFactory.getFont("STSong-Light", "UniGB-UCS2-H", Font.DEFAULTSIZE);
    
        }
    
        public String getMimeType()
        {
            return "application/pdf"; 
        }
    
        /**
         * The overall PDF table generator.
         * @throws JspException for errors during value retrieving from the table model
         * @throws BadElementException IText exception
         */
        protected void generatePDFTable() throws JspException, BadElementException
        {
            if (this.header)
            {
                generateHeaders();
            }
            tablePDF.endHeaders();
            generateRows();
        }
    
        /**
         * @see org.displaytag.export.BinaryExportView#doExport(OutputStream)
         */
        public void doExport(OutputStream out) throws JspException
        {
            try
            {
                // Initialize the table with the appropriate number of columns
                initTable();
    
                // Initialize the Document and register it with PdfWriter listener and the OutputStream
                Document document = new Document(PageSize.A4.rotate(), 60, 60, 40, 40);
                document.addCreationDate();
                HeaderFooter footer = new HeaderFooter(new Phrase(TagConstants.EMPTY_STRING, smallFont), true);
                footer.setBorder(Rectangle.NO_BORDER);
                footer.setAlignment(Element.ALIGN_CENTER);
    
                PdfWriter.getInstance(document, out);
    
                // Fill the virtual PDF table with the necessary data
                generatePDFTable();
                document.open();
                document.setFooter(footer);
                document.add(this.tablePDF);
                document.close();
    
            }
            catch (Exception e)
            {
                throw new PdfGenerationException(e);
            }
        }
    
        /**
         * Generates the header cells, which persist on every page of the PDF document.
         * @throws BadElementException IText exception
         */
        protected void generateHeaders() throws BadElementException
        {
            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());
                }
    
                Cell hdrCell = getCell(columnHeader);
                hdrCell.setGrayFill(0.9f);
                hdrCell.setHeader(true);
                tablePDF.addCell(hdrCell);
    
            }
        }
    
        /**
         * Generates all the row cells.
         * @throws JspException for errors during value retrieving from the table model
         * @throws BadElementException errors while generating content
         */
        protected void generateRows() throws JspException, BadElementException
        {
            // 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();
    
                // 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);
    
                    Cell cell = getCell(ObjectUtils.toString(value));
                    tablePDF.addCell(cell);
                }
            }
        }
    
        /**
         * Returns a formatted cell for the given value.
         * @param value cell value
         * @return Cell
         * @throws BadElementException errors while generating content
         */
        private Cell getCell(String value) throws BadElementException
        {
            Cell cell = new Cell(new Chunk(StringUtils.trimToEmpty(value), smallFont));
            cell.setVerticalAlignment(Element.ALIGN_TOP);
            cell.setLeading(8);
            return cell;
        }
    
        /**
         * Wraps IText-generated exceptions.
         * @author Fabrizio Giustina
         * @version $Revision: 1081 $ ($Author: fgiust $)
         */
        static class PdfGenerationException 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 PdfGenerationException(Throwable cause)
            {
                super(PdfView.class, Messages.getString("PdfView.errorexporting"), cause); //$NON-NLS-1$
            }
    
            /**
             * @see org.displaytag.exception.BaseNestableJspTagException#getSeverity()
             */
            public SeverityEnum getSeverity()
            {
                return SeverityEnum.ERROR;
            }
        }
    }

    2 在web.xml中配置两个Filter,字符编码过滤器字符集设置为GBK

     直接来自原文件及包,只是将字体设置为支持中文的PDF字体。

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
    
        <display-name>OpenReports</display-name>    
        
        <context-param>
            <param-name>contextConfigLocation</param-name>
               <param-value>/WEB-INF/applicationContext*.xml</param-value>
          </context-param>
    
        <context-param>
            <param-name>contextFactory</param-name>
            <param-value>
                com.tonbeller.wcf.controller.RequestContextFactoryImpl
            </param-value>
        </context-param>
         
        <filter>
            <filter-name>struts</filter-name>
            <filter-class>
                org.apache.struts2.dispatcher.FilterDispatcher
            </filter-class>
        </filter>
        
        <!-- support the chinese  add filter  start -->
        <!-- 
        <filter>
            <filter-name>ResponseOverrideFilter</filter-name>
            <filter-class>
                org.displaytag.filter.ResponseOverrideFilter
            </filter-class>
        </filter>
         -->
        <filter>
            <filter-name>ResponseOverrideFilter</filter-name>
            <filter-class>
                cn.ResponseOverrideFilter<!-- org.displaytag.filter -->
            </filter-class>
        </filter>
        
        <filter>
            <filter-name>encodingFilter</filter-name>
            <filter-class>
                cn.SetCharacterEncodingFilter
            </filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>GBK</param-value>
            </init-param>
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
         
        <!-- support the chinese  add filter end-->
    
        <filter>
            <filter-name>JPivotController</filter-name>
            <filter-class>
                com.tonbeller.wcf.controller.RequestFilter
            </filter-class>
            <!--
            <init-param>
                <param-name>indexJSP</param-name>
                <param-value>/index.html</param-value>
                <description>
                    forward to this page if session is new
                </description>
            </init-param>
            <init-param>
                <param-name>errorJSP</param-name>
                <param-value>/error.jsp</param-value>
                <description>URI of error page</description>
            </init-param>
            <init-param>
                <param-name>busyJSP</param-name>
                <param-value>/busy.jsp</param-value>
                <description>
                    This page is displayed if a the user clicks on a query
                    before the previous query has finished
                </description>
            </init-param>
            
                <init-param>
                <param-name>forceExtension</param-name>
                <param-value>.faces</param-value>
                <description>replace .jsp with .faces</description>
                </init-param>
            -->
        </filter>
        <!-- support the chinese   add mapping start -->
        <filter-mapping>
            <filter-name>ResponseOverrideFilter</filter-name>
            <url-pattern>*.action</url-pattern>
        </filter-mapping>
        <filter-mapping>
            <filter-name>encodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <!-- support the chinese   add mapping start -->
    
        <filter-mapping>
            <filter-name>JPivotController</filter-name>
            <url-pattern>/jpivot.action</url-pattern>
        </filter-mapping>
        
        <filter-mapping>
            <filter-name>JPivotController</filter-name>
            <url-pattern>/JPivot.jsp</url-pattern>
        </filter-mapping>
        
        <filter-mapping>
            <filter-name>ResponseOverrideFilter</filter-name>
            <url-pattern>*.action</url-pattern>
        </filter-mapping>
    
        <filter-mapping>
            <filter-name>struts</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
        <!-- resources initializer -->
        <listener>
            <listener-class>
                com.tonbeller.tbutils.res.ResourcesFactoryContextListener
            </listener-class>
        </listener>
    
        <listener>
            <listener-class>
                org.springframework.web.context.ContextLoaderListener
            </listener-class>
        </listener>
        
        <servlet>
            <servlet-name>JspSupportServlet</servlet-name>
            <servlet-class>
                org.apache.struts2.views.JspSupportServlet
            </servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <servlet>
            <servlet-name>fileServlet</servlet-name>
            <servlet-class>
                org.efs.openreports.dispatcher.FileDispatcher
            </servlet-class>
            <load-on-startup>99</load-on-startup>
        </servlet>
    
        <servlet>
            <servlet-name>MondrianXmlaServlet</servlet-name>
            <servlet-class>
                org.efs.openreports.dispatcher.XMLADispatcher
            </servlet-class>
        </servlet>
        
        <servlet>
            <servlet-name>XFireServlet</servlet-name>
            <display-name>XFire Servlet</display-name>
            <servlet-class>
                org.codehaus.xfire.spring.XFireSpringServlet
            </servlet-class>
        </servlet>    
    
        <!-- jfreechart provided servlet -->
        <servlet>
            <servlet-name>DisplayChart</servlet-name>
            <servlet-class>
                org.jfree.chart.servlet.DisplayChart
            </servlet-class>
        </servlet>
    
        <!-- jfreechart provided servlet -->
        <servlet>
            <servlet-name>GetChart</servlet-name>
            <display-name>GetChart</display-name>
            <description>
                Default configuration created for servlet.
            </description>
            <servlet-class>
                com.tonbeller.jpivot.chart.GetChart
            </servlet-class>
        </servlet>
        <servlet>
            <servlet-name>Print</servlet-name>
            <display-name>Print</display-name>
            <description>
                Default configuration created for servlet.
            </description>
            <servlet-class>
                com.tonbeller.jpivot.print.PrintServlet
            </servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>DisplayChart</servlet-name>
            <url-pattern>/DisplayChart</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
            <servlet-name>Print</servlet-name>
            <url-pattern>/Print</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
            <servlet-name>GetChart</servlet-name>
            <url-pattern>/GetChart</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
            <servlet-name>fileServlet</servlet-name>
            <url-pattern>/report-images/*</url-pattern>
        </servlet-mapping>
    
        <servlet-mapping>
            <servlet-name>fileServlet</servlet-name>
            <url-pattern>/report-files/*</url-pattern>
        </servlet-mapping>
        
        <servlet-mapping>
            <servlet-name>XFireServlet</servlet-name>
            <url-pattern>/services/*</url-pattern>
        </servlet-mapping>
    
        <servlet-mapping>
            <servlet-name>MondrianXmlaServlet</servlet-name>
            <url-pattern>/xmla</url-pattern>
        </servlet-mapping>
    
        <welcome-file-list>
            <welcome-file>/Login.jsp</welcome-file>
        </welcome-file-list>
    
        <taglib>
            <taglib-uri>http://www.tonbeller.com/wcf</taglib-uri>
            <taglib-location>/WEB-INF/wcf/wcf-tags.tld</taglib-location>
        </taglib>
    
        <taglib>
            <taglib-uri>http://www.tonbeller.com/jpivot</taglib-uri>
            <taglib-location>
                /WEB-INF/jpivot/jpivot-tags.tld
            </taglib-location>
        </taglib>
    
    </web-app>

    3 增加PDF中文支持的JAR包

    4 struts.properties配置文件字符编码改为GBK

    ## when set to true, Struts will act much more friendly for developers. This
    ### includes:
    ### - struts.i18n.reload = true
    ### - struts.configuration.xml.reload = true
    ### - raising various debug or ignorable problems to errors
    ###   For example: normally a request to foo.action?someUnknownField=true should
    ###                be ignored (given that any value can come from the web and it
    ###                should not be trusted). However, during development, it may be
    ###                useful to know when these errors are happening and be told of
    ###                them right away.
    struts.devMode=false
    
    ### Load custom default resource bundles
    struts.custom.i18n.resources=LocalStrings
    
    ### This can be used to set your default locale and encoding scheme
    #support the chinese   start
    #struts.locale=en_US
    #struts.i18n.encoding=UTF-8
    struts.locale=zh_CN
    struts.i18n.encoding=GBK
    
    #support the chinese   start
    
    ### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data
    struts.multipart.parser=org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest 

    5 国际化配置文件

    屏蔽原来的:LocalStrings.properties文件,新增:LocalStrings_zh_CN.properties文件

    翻译如下:

    error.report.empty=The report is empty. Please try different parameters.
    error.validation.notsupported=Validation not supported on queries with parameters.
    error.exporttype.required=You must select at least one Export Type.
    error.invalid.password=Invalid Password: Both passwords must be equal.
    error.login.incomplete=Please Enter Both User Name and Password.
    error.login.invalid=Invalid User Name or Password!
    error.report.invalid=Invalid report.
    error.report.notauthorized=You are not authorized to view this Report.
    error.reportgroup.notauthorized=You are not authorized to view this Report Group.
    error.emailaddress.required=You must update your email address before scheduling reports!
    error.dateandtime.required=Start Date and Time required to schedule report.
    error.dateandtime.invalid=Start Time invalid.
    error.notauthorized=You are not authorized to perform this action. 
    error.notloggedin=You are not currently logged into the system. 
    error.invalid.user=You are not a valid OpenReports User. Please contact Administrator.
    error.chartquery.invalid=Invalid Chart Query
    error.alertquery.invalid=Invalid Alert Query
    error.testing.connection=Error testing connection, verify DataSource configuration and try again
    error.parameter.required=Please Fill Required Parameter
    error.chart.deletion=Report Chart must be removed from all reports before deletion.
    error.datasource.deletion=This DataSource is being used by Reports or Parameters and cannot be deleted.
    error.group.deletion=Report Group must be removed from all users before deletion.s
    error.parameter.deletion=Report Parameter must be removed from all reports before deletion.
    error.report.deletion=Report must be removed from all Report Groups before deletion.
    error.parameter.notfound=Parameter not found
    error.alert.deletion=This alert is associated with a user and can not be deleted.
    error.unique.constraint=This name is already in use. Please use a unique name.
    error.invalid.maxrows=QueryReport MaxRows must be set to a valid number. 500 is recommended.
    error.chart.invalid=Name, description, and query are required.
    error.xmla.properties.invalid=XMLA DataSource, URI, and Catalog properties must be set.
    error.serverside=There has been an error on the server. Please check the logs.
    error.settings.directories=Directories not configured correctly. Please recheck General Settings.
    
    alert.failed=Failed
    alert.passed=Passed
    
    message.schedule.successful=Report scheduled successfully...
    
    service.request.complete=COMPLETE
    
    application.title=u7F51u7EDCu81EAu5B9Au4E49u62A5u8868
    
    banner.logoff=u6ce8u9500
    banner.reports=u6211u7684u62a5u8868
    banner.scheduledReports=u5b9au65f6u4efbu52a1u62a5u8868
    banner.administration=u7cfbu7edfu7ba1u7406
    banner.dashboard=Dashboard
    banner.preferences=u4feeu6539u7528u6237u4fe1u606f
    
    button.save=u4fddu5b58
    button.cancel=u5220u9664
    button.add=u589eu52a0
    button.delete=u5220u9664
    button.update=u66f4u65b0
    button.refresh=u5237u65b0
    button.submit=u63d0u4ea4
    button.duplicate=u590du5236
    button.validate=u6821u9a8c
    button.addGroup=u589eu52a0u62a5u8868u5206u7ec4
    button.addDataSource=u589eu52a0u6570u636eu6e90
    button.autoCreate=u81eau52a8u751fu6210
    button.autoAdd=u81eau52a8u589eu52a0
    button.addNew=u65b0u589e
    button.addChart=u589eu52a0u56feu8868
    button.addReportFile=u589eu52a0u62a5u8868u6a21u677f
    button.addReports=u589eu52a0u62a5u8868
    button.cleanup=u6e05u9664
    button.export=u5bfcu51fa
    button.import=u5bfcu5165
    
    label.username=u7528u6237u540Du79F0
    label.password=u7528u6237u5bc6u7801
    label.confirmPassword=u786eu8ba4u5bc6u7801
    label.email=u90aeu7bb1u5730u5740
    label.dashboardReport=Dashboard Report
    label.name=u540du79f0
    label.externalId=External ID
    label.description=u63cfu8ff0
    label.report=Report
    label.startDate=u8d77u59cbu65e5u671f
    label.scheduleType=u4efbu52a1u7c7bu578b
    label.scheduleState=State
    label.nextRun=Next Run
    label.runDate=Run Date
    label.alert=Alert
    label.operator=Operator
    label.limit=Limit
    label.status=Status
    label.startTime=u5f00u59cbu65f6u95f4
    label.elapsedTime=Duration (sec)
    label.message=u4fe1u606f
    label.cronExpression=Cron Expression
    label.numberOfHours=# of Hours     
    label.condition=Condition     
    label.recipients=Recipients
    label.options=Options
    label.once=u4e00u6b21
    label.daily=u6bcfu5929
    label.weekdays=u6bcfu5468u67d0u65e5
    label.weekly=u6bcfu5468
    label.cron=Cron 
    label.monthly=u6bcfu6708
    label.hourly=u6bcfu5c0fu65f6
    label.action=Action
    label.tags=Tags
    label.groups=Groups
    label.roles=Roles
    label.filter=Filter
    label.filterBy=Filter By
    label.required=u5fc5u987b
    label.class=u53c2u6570u7c7bu578b
    label.type=u7c7bu578b
    label.id=Id
    label.data=u6570u636e
    label.dataSource=u6570u636eu6e90
    label.multipleSelect=u591au9009
    label.useJNDI=u4f7fu7528u6570u636eu6e90
    label.url=URL
    label.driver=u6570u636eu5e93u9a71u52a8u7a0bu5e8f     
    label.maxIdle=u6700u5927u8fdeu63a5u6570
    label.maxActive=u6700u5927u6d3bu8dc3u8fdeu63a5u6570
    label.maxWait=u6700u5927u7b49u5f85u65f6u95f4
    label.validationQuery=u68c0u9a8cu67e5u8be2u8bedu53e5
    label.query=u67e5u8be2u8bedu53e5
    label.chart=u56feu8868
    label.hidden=u9690u85cf
    label.reportFile=u62a5u8868u6a21u677f
    label.exportTypes=u62a5u8868u7c7bu578b
    label.virtualization=Use Virtualization
    label.step=u6b65u9aa4
    label.sortOrder=u6392u5e8fu987au5e8f
    label.reportParameter=u62a5u8868u53c2u6570
    label.exportFormat=Export Format
    label.exportOption=Export Option
    label.chartType=u56feu8868u7c7bu578b
    label.width=u5bbd
    label.height=u9ad8
    label.xAxisLabel=Xu5750u6807u8f74u540du79f0
    label.yAxisLabel=Yu5750u6807u8f74u540du79f0
    label.showTitle=u663eu793au6807u9898
    label.showLegend=u663eu793au56feu4f8b
    label.showValues=u663eu793au503c
    label.plotOrientation=u56feu5f62u65b9u5411
    label.drillDownReport=u4e0bu94bbu62a5u8868
    label.horizontal=u6c34u5e73u65b9u5411
    label.vertical=u6c34u5e73u65b9u5411
    label.baseDirectory=Base Directory    
    label.reportGenerationDirectory=Report Generation Directory
    label.tempDirectory=Temp Directory
    label.dateFormat=Date Format          
    label.queryReportMaxRows=Query Report Max Rows
    label.mailHost=Mail Host
    label.useMailAuthenticator=Use Mail Authenticator
    label.mailAuthenticatorUser=Mail Authenticator UserName          
    label.mailAuthenticatorPassword=Mail Authenticator Password          
    label.xmlaURI=XMLA URI           
    label.xmlaDataSource=XMLA DataSource          
    label.xmlaCatalog=XMLA Catalog
    label.numberOfFiles=File Count
    label.directorySize=Directory Size
    label.reports=u6211u7684u62a5u8868
    label.currentState=Current State
    label.hits=Hits
    label.user=User
    label.value=Value
    label.alerts=Alerts
    label.defaultValue=u9ed8u8ba4u503c
    
    link.back.groups=u8fd4u56deu62a5u8868u7ec4
    link.back.reports=u8fd4u56deu62a5u8868
    link.back.parameters=Back to Parameters
    link.back.charts=u8fd4u56deu56feu8868
    link.back.dataSources=u8fd4u56deu6570u636eu6e90
    link.back.users=Back to Users
    link.back.admin=u8fd4u56deu5230u7cfbu7edfu7ba1u7406
    link.back.alerts=Back to Alerts
    link.delete=u5220u9664
    link.update=u66f4u65b0
    link.groups=u62a5u8868u7ec4
    link.users=u7528u6237
    link.admin.reports=u62a5u8868
    link.admin.reportParameters=u62a5u8868u53c2u6570
    link.admin.dataSources=u6570u636eu6e90
    link.admin.charts=u56feu8868
    link.admin.alerts=u8b66u62a5
    link.admin.groups=u62a5u8868u7ec4
    link.admin.users=u7528u6237
    link.admin.scheduler=Scheduler
    link.admin.settings=u8bbeu7f6e
    link.admin.statistics=Statistics
    link.admin.logs=u67e5u770bu65e5u5fd7
    link.admin.addUser=u65b0u589eu7528u6237
    link.admin.addReport=u65b0u589eu62a5u8868
    link.admin.addReportParameter=u65b0u589eu62a5u8868u53c2u6570
    link.admin.addReportGroup=u65b0u589eu62a5u8868u7ec4
    link.admin.addDataSource=u65b0u589eu6570u636eu6e90
    link.admin.addChart=u65b0u589eu56feu8868
    link.admin.addAlert=u65b0u589eu8b66u62a5
    link.admin.uploadReport=u4e0au4f20u62a5u8868u6587u4ef6
    link.admin.search=u641cu7d22
    link.admin.import=u5bfcu5165u62a5u8868
    link.admin.export=u5bfcu51fau62a5u8868
    link.scheduleChart=Schedule ChartReport
    
    role.advancedScheduler=Advanced Scheduler                
    role.chartAdmin=Chart Admin
    role.dataSourceAdmin=DataSource Admin    
    role.uploader=File Uploader
    role.groupAdmin=Group Admin
    role.logViewer=Log Viewer    
    role.parameterAdmin=Parameter Admin
    role.reportAdmin=Report Admin
    role.rootAdmin=Root Admin
    role.scheduler=Scheduler
    role.dashboard=Dashboard User
    role.schedulerAdmin=Scheduler Admin
    role.alerts=Alerts User
    role.alertAdmin=Alerts Admin
    
    login.title=u8bf7u767bu5f55
    login.submit=u767bu5f55
    reportGroup.title=Groups
    reportList.title=u62a5u8868
    reportDetail.title=u53c2u6570:
    reportDetail.requiredParameters=* Indicates required parameters
    reportOptions.title=Export Options for:
    reportOptions.exportType=Export Type
    reportOptions.description=Email/File Description
    reportOptions.run=Run
    reportOptions.runNewWindow=u5728u65b0u7a97u53e3u6253u5f00
    reportOptions.schedule=Schedule
    reportOptions.sendToFile=Send to File
    reportOptions.sendToEmail=Send to Email
    reportOptions.note=Only applies when 'Send to Email' or 'Send to File' is clicked.
    listScheduledReports.scheduledReports=u5b9au65f6u4efbu52a1u62a5u8868
    listScheduledReports.generatedReports=Generated Reports
    userAdmin.preferences=u4feeu6539u7528u6237u4fe1u606f
    userAdmin.alerts=Alerts
    deleteReport.warning=This will remove the report from all groups and delete all entries for the report in the logs.
    deleteReport.title=Delete Report Confirmation
    deleteReportParameter.title=Delete Report Parameter Confirmation
    deleteDataSource.title=Delete DataSource Confirmation
    deleteAlert.title=Delete Alert Confirmation
    deleteAlert.warning=This will remove the alert and delete all entries for the alert in the logs.
    deleteChart.title=Delete Chart Confirmation
    deleteGroup.title=Delete Group Confirmation
    deleteUser.title=Delete User Confirmation
    deleteUser.warning=This will delete all entries for this user in the logs.
    deleteScheduledReport.title=Delete Scheduled Report Confirmation
    deleteGeneratedReport.title=Delete Generated Report Confirmation
    uploadReportFiles.uploadFile=u4e0au4f20u62a5u8868u6587u4ef6
    uploadReportFiles.currentFiles=u5f53u524du62a5u8868u6587u4ef6
    reportViewer.page=Page
    reportViewer.zoom=Zoom
    viewReportLogs.title=Log Filters
    viewReportLogs.warning=Log query results limited to 500 rows 
    reportSchedule.title=u5b9au65f6u4efbu52a1u62a5u8868u9009u9879:
    reportSchedule.sendToFile=Send to File
    reportSchedule.message.hours=# of Hours only applies to Hourly scheduled Reports
    reportSchedule.message.cron=Cron Expression only applies to Cron scheduled Reports
    reportAdmin.tab.reportAdmin=u62a5u8868u7ba1u7406
    reportAdmin.tab.userAdmin=u7528u6237u7ba1u7406
    reportAdmin.tab.generalAdmin=u65e5u5e38u7ba1u7406
    reportAdmin.message.reports=u589eu52a0u6216u4feeu6539u62a5u8868uff0cu4e0au4f20u62a5u8868u6a21u677fuff0cu5206u914du62a5u8868u5230u62a5u8868u7ec4.
    reportAdmin.message.search=u901au8fc7u5907u6ce8u6216u8bf4u660eu67e5u8be2u62a5u8868uff0cu62a5u8868u7ec4uff0cu7528u6237.
    reportAdmin.message.logs=u67e5u770bu62a5u8868u64cdu4f5cu65e5u5fd7uff0cu901au8fc7u65e5u671fu3001u62a5u8868u3001u7528u6237u6216u72b6u6001.
    reportAdmin.message.reportParameters=u589eu52a0u6216u4feeu6539u62a5u8868u53c2u6570.
    reportAdmin.message.dataSources=u589eu52a0u6216u4feeu6539u6570u636eu6e90.
    reportAdmin.message.alerts=Add or Modify Alerts.
    reportAdmin.message.charts=u589eu52a0u6216u4feeu6539u56feu6807.
    reportAdmin.message.groups=u589eu52a0u6216u4feeu6539u62a5u8868u7ec4uff0cu5206u914du7528u6237u5230u62a5u8868u7ec4.
    reportAdmin.message.users=u589eu52a0u6216u4feeu6539u7528u6237.
    reportAdmin.message.scheduler=Global Scheduler Administration
    reportAdmin.message.settings=u65e5u5e38u8bbeu7f6eu5305u62ecu90aeu4ef6u4e3bu673au548cu62a5u8868u76eeu5f55.
    reportAdmin.message.statistics=View Top Reports by user, date or status.
    reportAdmin.message.import=Import Report definitions from XML.
    reportAdmin.message.export=Export Report definitions to XML.
    queryReport.scheduleReport=Schedule Report:
    listSearchResults.title=Search by tag:
    editUser.addUser=u65b0u589eu7528u6237:
    editUser.selectedUser=u6240u9009u7684u7528u6237:
    editReportParameter.addReportParameter=Add Report Parameter:
    editReportParameter.selectedReportParameter=u9009u62e9u7684u62a5u8868u53c2u6570:
    editUser.selectedUser=u6240u9009u7684u7528u6237:
    editReportParameter.parameterValues=Parameter Values
    editReportGroups.title=Report Groups: 
    editReport.tab.reportDefinition=u62a5u8868u5b9au4e49
    editReport.tab.reportParameters=u62a5u8868u53c2u6570
    editReport.tab.jasperReportOptions=u62a5u8868u5bfcu51fau9009u9879
    editReport.parameters.autoAdd= <b>Auto Add</b> inspects the report design and adds all parameters that match the name of existing OpenReports parameters.
    editReport.parameters.autoCreate=<b>Auto Create</b> is the same as <b>Auto Add</b> except that it also creates new Text Parameters for all parameters where a match is not found.
    editReport.parameters.addNew=<b>u65b0u589e</b> u5f39u51fau65b0u589eu53c2u6570u7a97u53e3uff0cu65b0u5efau4e00u4e2au62a5u8868u53c2u6570u3002.
    editReport.jasperOption.removeEmptySpaceBetweenRows=Remove Empty Space Between Rows
    editReport.jasperOption.whitePageBackground=White Page Background
    editReport.jasperOption.onePagePerSheet=One Page Per Sheet
    editReport.jasperOption.wrapBreakWord=Wrap Break Word
    editReport.jasperOption.usingImagesToAlign=Using Images To Align
    editReport.jasperOption.autoDetectCellType=Auto Detect Cell Type
    editProperties.tab.generalSettings=General Settings
    editProperties.tab.tempFileCleanup=Temp File Cleanup
    editGroupUsers.title=Group User Assignment:
    editGroup.addReportsToGroup.title=Add Reports To Group
    editGroup.addGroup=Add Group:
    editGroup.selectedGroup=u9009u62e9u7684u7528u6237:
    editDataSource.addDataSource=Add DataSource:
    editDataSource.selectedDataSource=u9009u62e9u7684u6570u636eu6e90:
    editChart.addChart=Add Chart:
    editChart.selectedChart=u9009u62e9u7684u56feu8868:
    editAlert.addAlert=u65b0u589eu8b66u62a5:
    editAlert.selectedAlert=u9009u62e9u7684u8b66u62a5:
    addDataSourceDialog.title=u65b0u589eu6570u636eu6e90
    addChartDialog.title=u65b0u589eu56feu8868
    addReportFileDialog.title=u4e0au4f20u62a5u8868u6a21u677f
    addReportParameterDialog.title=u65b0u589eu62a5u8868u53c2u6570
    changeScheduleState.title=Change Schedule State Confirmation
    analyzeReportLogs.title=Report Statistics
    analyzeReportLogs.query.topReports=Top Reports
    analyzeReportLogs.query.topReportsByUser=Top Reports By User
    analyzeReportLogs.query.topReports30Days=Top Reports - Last 30 Days
    analyzeReportLogs.query.topReports60Days=Top Reports - Last 60 Days
    analyzeReportLogs.query.topReports90Days=Top Reports - Last 90 Days
    analyzeReportLogs.query.topFailures=Top Failed Reports
    analyzeReportLogs.query.topEmpty=Top Empty Reports
    analyzeReportLogs.query.topAlerts=Top Alerts
    analyzeReportLogs.query.topAlertsByUser=Top Alerts - By User
    analyzeReportLogs.query.topTriggeredAlerts=Top Alerts - Triggered
    analyzeReportLogs.query.topNotTriggeredAlerts=Top Alerts - Not Triggered
    dashboard.message=Use the <a href="userAdmin.action">Preferences</a> link to add Alerts and set your Dashboard report.
    dataExport.title=Export Report Definitions
    dataImport.title=Import Report Definitions    
    
    tooltip.parameter.class=The Java class of the parameter. Used for validation and passed to reports.
    tooltip.parameter.data=Enter SQL for Query parameters or pipe '|' seperated list of values for List parameters.
    tooltip.parameter.dataSource=Used only with Query parameters.
    tooltip.parameter.multiSelect=Determines if the parameter allows multiple selections. Valid only for Query and List parameters.
    
    tooltip.datasource.driver=JDBC Driver class. The JDBC driver containing this class must be in the OpenReports classpath.
    tooltip.datasource.jndi=Lookup JNDI DataSource. JNDI DataSources require only Name and URL.
    tooltip.datasource.maxActive=The maximum number of active connections that can be allocated from this pool at the same time, or negative for no limit.
    tooltip.datasource.maxIdle=The maximum number of active connections that can remain idle in the pool, without extra ones being released, or zero for no limit.
    tooltip.datasource.maxWait=The maximum number of milliseconds that the pool will wait (when there are no available connections) for a connection to be returned before throwing an exception, or -1 to wait indefinitely.
    tooltip.datasource.query=The SQL query that will be used to validate connections from this pool before returning them to the caller. If specified, this query MUST be an SQL SELECT statement that returns at least one row.
    tooltip.datasource.url=JNDI DataSource name or JDBC Database URL
    
    tooltip.report.chart=Select chart for use in ChartReports.
    tooltip.report.export=Export Types. Not all export types supported by all report engines.
    tooltip.report.file=Select the report template file. Not required for QueryReports or ChartReports.
    tooltip.report.hidden=If checked, this report will not be displayed to end users. Useful for DrillDown reports.
    tooltip.report.query=Enter SQL query for use with QueryReports or JXLS template.
    tooltip.report.virtualization=Enable Virtualization for JasperReports. 
    
    tooltip.chart.plotOrientation=Plot Orientation. Only applicable for Bar and XY Charts
    tooltip.chart.query=Chart SQL Query. See OpenReports Adminstration Guide for valid Chart query formats.
    tooltip.chart.values=If this option is checked, the Chart Values will be displayed in a sortable table below the Chart.
    tooltip.chart.xlabel=X-Axis label. Not applicable for Pie Charts
    tooltip.chart.ylabel=Y-Axis label. Not applicable for Pie Charts
    
    tooltip.properties.baseDirectory=Full path to directory containing report files
    tooltip.properties.reportGenerationDirectory=Full path to directory used to store reports generated to files
    tooltip.properties.tempDirectory=Full path to directory for temp files
    tooltip.properties.maxRows=Maximum number of rows returned per QueryReport
    tooltip.properties.mailhost=Mail Host required for scheduled reports
    tooltip.properties.mailAuthenticator=Check this box if your Mail Host requires a UserName and Password    
    
    tooltip.alert.query=Alert SQL Query. Must return an Integer. For example: SELECT count(*) FROM address

    6修改displaytag.properties配置文件

    翻译如下:

    factory.decorator=org.efs.openreports.util.displaytag.SpringDecoratorFactory
    locale.resolver = org.efs.openreports.util.displaytag.DisplayTagI18nStruts2Adapter
    locale.provider = org.efs.openreports.util.displaytag.DisplayTagI18nStruts2Adapter
    basic.empty.showtable=true
    
    paging.banner.placement=bottom
    paging.banner.item_name=u8bb0u5f55
    paging.banner.items_name=u8bb0u5f55
    paging.banner.no_items_found=<span class ="pagebanner">u6ca1u6709{0}u627eu5230.</span>
    paging.banner.one_item_found=<span class ="pagebanner">u4e00u6761{0}u627eu5230.</span>
    paging.banner.all_items_found=<span class ="pagebanner">{0}{1}u627eu5230,u663eu793au5168u90e8{2}.</span>
    paging.banner.some_items_found=<span class ="pagebanner">u5171u627eu5230{0}{1},u663eu793a{2}u5230{3}.</span>
    paging.banner.full=<span class ="pagelinks">[<a href="{1}">u7b2cu4e00u9875</a>/<a href="{2}">u4e0au4e00u9875</a>] {0} [<a href="{3}">u4e0bu4e00u9875</a>/<a href="{4}">u6700u540eu4e00u9875</a>]</span>
    paging.banner.first=<span class ="pagelinks">[u7b2cu4e00u9875/u4e0au4e00u9875] {0} [<a href="{3}">u4e0bu4e00u9875</a>/<a href="{4}">u6700u540eu4e00u9875</a>]</span>
    paging.banner.last=<span class ="pagelinks">[<a href="{1}">u7b2cu4e00u9875</a>/<a href="{2}">u4e0au4e00u9875</a>] {0} [u4e0bu4e00u9875/u6700u540eu4e00u9875]</span>
    paging.banner.onepage=<span class ="pagelinks">{0}</span>
    paging.banner.page.selected=<strong>{0}</strong>
    paging.banner.page.link=<a.href="{1}" title+"u8f6cu5230u9875 {0}">{0}</a>
    paging.banner=<div class="explortlinks">u5bfcu51fau7c7bu578b:{0}</div>
    
     

    7、JSP页面文件字符集全部改为GBK

  • 相关阅读:
    #什么是spring#
    spark sql 判断一列是否包含某字符
    win10 安装微软商店
    python获取一段时间的日期
    css 网格
    css 网格属性总结
    css flex容器属性总结
    CSS Flexbox
    响应式Web设计
    css 伪类选择器
  • 原文地址:https://www.cnblogs.com/shindo/p/4958767.html
Copyright © 2011-2022 走看看