Saiku图表导出时中文显示问题的解决方法

Saiku图表导出时png,jpg,pdf三种格式的中文显示都有问题,目前找到一种不太完善的解决方法(中文可以显示但不清晰),需要修改Saiku项目下的ExporterResource.java文件,同时需要在项目Linux环境中安装中文字体,完成后重启项目即可。

后续找到更好的解决方案时会更新此文或者给出新文章地址。

Linux环境中安装中文字体请参考:http://blog.163.com/[email protected]/blog/static/13673931220147442149228/?newFollowBlog

ExporterResource.java文件修改如下:

/*
 *   Copyright 2012 OSBI Ltd
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package org.saiku.web.rest.resources;

import org.saiku.olap.query2.ThinQuery;
import org.saiku.web.rest.objects.resultset.QueryResult;
import org.saiku.web.rest.util.ServletUtil;
import org.saiku.web.svg.Converter;

import com.lowagie.text.Document;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;

import org.apache.batik.svggen.SVGConverter;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

/**
 * QueryServlet contains all the methods required when manipulating an OLAP Query.
 * @author Paul Stoellberger
 *
 */
@Component
@Path("/saiku/{username}/export")
@XmlAccessorType(XmlAccessType.NONE)
public class ExporterResource {

    private static final Logger log = LoggerFactory.getLogger(ExporterResource.class);

    private ISaikuRepository repository;

    private Query2Resource query2Resource;

    public void setQuery2Resource(Query2Resource qr){
        this.query2Resource = qr;
    }

    public void setRepository(ISaikuRepository repository){
        this.repository = repository;
    }

  /**
   * Export query to excel file format.
   * @summary Export to excel.
   * @param file The file
   * @param formatter The cellset formatter
   * @param name The name
   * @param servletRequest The servlet request.
   * @return A response containing an excel file.
   */
    @GET
    @Produces({"application/json" })
    @Path("/saiku/xls")
    public Response exportExcel(@QueryParam("file") String file,
            @QueryParam("formatter") String formatter,@QueryParam("name") String name,
            @Context HttpServletRequest servletRequest)
    {
        try {
            Response f = repository.getResource(file);
            String fileContent = new String( (byte[]) f.getEntity());
            String queryName = UUID.randomUUID().toString();
            //fileContent = ServletUtil.replaceParameters(servletRequest, fileContent);
//            queryResource.createQuery(queryName,  null,  null, null, fileContent, queryName, null);
//            queryResource.execute(queryName, formatter, 0);
            Map<String, String> parameters = ServletUtil.getParameters(servletRequest);
            ThinQuery tq = query2Resource.createQuery(queryName, fileContent, null, null);
            if (parameters != null) {
                tq.getParameters().putAll(parameters);
            }
          if (StringUtils.isNotBlank(formatter)) {
            HashMap<String, Object> p = new HashMap<String, Object>();
            p.put("saiku.olap.result.formatter", formatter);
            if (tq.getProperties() == null) {
              tq.setProperties(p);
            } else {
              tq.getProperties().putAll(p);
            }
          }
            query2Resource.execute(tq);
            return query2Resource.getQueryExcelExport(queryName, formatter, name);
        } catch (Exception e) {
            log.error("Error exporting XLS for file: " + file, e);
            return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
        }
    }

  /**
   * Export the query to a CSV file format.
   * @summary Export to CSV.
   * @param file The file
   * @param formatter The cellset formatter
   * @param servletRequest The servlet request
   * @return A response containing a CSV file.
   */
    @GET
    @Produces({"application/json" })
    @Path("/saiku/csv")
    public Response exportCsv(@QueryParam("file") String file,
            @QueryParam("formatter") String formatter,
            @Context HttpServletRequest servletRequest)
    {
        try {
            Response f = repository.getResource(file);
            String fileContent = new String( (byte[]) f.getEntity());
            //fileContent = ServletUtil.replaceParameters(servletRequest, fileContent);
            String queryName = UUID.randomUUID().toString();
//            query2Resource.createQuery(null,  null,  null, null, fileContent, queryName, null);
//            query2Resource.execute(queryName,formatter, 0);
            Map<String, String> parameters = ServletUtil.getParameters(servletRequest);
            ThinQuery tq = query2Resource.createQuery(queryName, fileContent, null, null);
            if (parameters != null) {
                tq.getParameters().putAll(parameters);
            }

          if (StringUtils.isNotBlank(formatter)) {
            HashMap<String, Object> p = new HashMap<String, Object>();
            p.put("saiku.olap.result.formatter", formatter);
            if (tq.getProperties() == null) {
              tq.setProperties(p);
            } else {
              tq.getProperties().putAll(p);
            }
          }
            query2Resource.execute(tq);
            return query2Resource.getQueryCsvExport(queryName);
        } catch (Exception e) {
            log.error("Error exporting CSV for file: " + file, e);
            return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
        }
    }

  /**
   * Export the query response to JSON.
   * @summary Export to JSON
   * @param file The file
   * @param formatter The cellset formatter
   * @param servletRequest The servlet request
   * @return A response containing a JSON query response.
   */
    @GET
    @Produces({"application/json" })
    @Path("/saiku/json")
    public Response exportJson(@QueryParam("file") String file,
            @QueryParam("formatter") String formatter,
            @Context HttpServletRequest servletRequest)
    {
        try {
            Response f = repository.getResource(file);
            String fileContent = new String( (byte[]) f.getEntity());
            fileContent = ServletUtil.replaceParameters(servletRequest, fileContent);
            String queryName = UUID.randomUUID().toString();
//            query2Resource.createQuery(null,  null,  null, null, fileContent, queryName, null);
//            QueryResult qr = query2Resource.execute(queryName, formatter, 0);
            Map<String, String> parameters = ServletUtil.getParameters(servletRequest);
            ThinQuery tq = query2Resource.createQuery(queryName, fileContent, null, null);
            if (parameters != null) {
                tq.getParameters().putAll(parameters);
            }
          if (StringUtils.isNotBlank(formatter)) {
            HashMap<String, Object> p = new HashMap<String, Object>();
            p.put("saiku.olap.result.formatter", formatter);
            if (tq.getProperties() == null) {
              tq.setProperties(p);
            } else {
              tq.getProperties().putAll(p);
            }
          }
            QueryResult qr = query2Resource.execute(tq);
            return Response.ok().entity(qr).build();
        } catch (Exception e) {
            log.error("Error exporting JSON for file: " + file, e);
            return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
        }
    }

  /**
   * Export the current resultset to an HTML file.
   * @summary Export to HTML
   * @param file The file
   * @param formatter The formatter
   * @param css The css
   * @param tableonly Table only, or include chart
   * @param wrapcontent Wrap content
   * @param servletRequest The servlet reaquest.
   * @return A reponse containing the HTML export.
   */
  @GET
  @Produces({"text/html" })
  @Path("/saiku/html")
  public Response exportHtml(@QueryParam("file") String file,
                             @QueryParam("formatter") String formatter,
                             @QueryParam("css") @DefaultValue("false") Boolean css,
                             @QueryParam("tableonly") @DefaultValue("false") Boolean tableonly,
                             @QueryParam("wrapcontent") @DefaultValue("true") Boolean wrapcontent,
                             @Context HttpServletRequest servletRequest)
  {
    try {
      Response f = repository.getResource(file);
      String fileContent = new String( (byte[]) f.getEntity());
      fileContent = ServletUtil.replaceParameters(servletRequest, fileContent);
      String queryName = UUID.randomUUID().toString();
      query2Resource.createQuery(queryName, fileContent, null, null);
      return query2Resource.exportHtml(queryName, formatter, css, tableonly, wrapcontent);
    } catch (Exception e) {
      log.error("Error exporting JSON for file: " + file, e);
      return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }

  /**
   * Export chart to a file.
   * @summary Export Chart.
   * @param type The export type (png, svg, jpeg)
   * @param svg The SVG
   * @param size The size
   * @param name The name
   * @return A reponse containing the chart export.
   */
    @POST
    @Produces({"image/*" })
    @Path("/saiku/chart")
    public Response exportChart(
            @FormParam("type") @DefaultValue("png")  String type,
            @FormParam("svg") String svg,
            @FormParam("size") Integer size,
            @FormParam("name") String name)
    {
        try {
//            final String imageType = type.toUpperCase();
            Converter converter = Converter.byType("PDF");
            if (converter == null)
            {
                throw new Exception("Image convert is null");
            }

            //               resp.setContentType(converter.getContentType());
            //               resp.setHeader("Content-disposition", "attachment; filename=chart." + converter.getExtension());
            //               final Integer size = req.getParameter("size") != null? Integer.parseInt(req.getParameter("size")) : null;
            //               final String svgDocument = req.getParameter("svg");
            //               if (svgDocument == null)
            //               {
            //                   resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing ‘svg‘ parameter");
            //                   return;
            //               }
            if (StringUtils.isBlank(svg)) {
                throw new Exception("Missing ‘svg‘ parameter");
            }
//            final InputStream in = new ByteArrayInputStream(svg.getBytes("UTF-8"));
//            final ByteArrayOutputStream out = new ByteArrayOutputStream();
//            converter.convert(in, out, size);
//            out.flush();
//            byte[] doc = out.toByteArray();
//          byte[] b = null;
          /*if(getVersion()!=null && !getVersion().contains("EE")) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            PdfReader reader = new PdfReader(doc);
            PdfStamper pdfStamper = new PdfStamper(reader,
                baos);

            URL dir_url = ExporterResource.class.getResource("/org/saiku/web/svg/watermark.png");
            Image image = Image.getInstance(dir_url);

            for (int i = 1; i <= reader.getNumberOfPages(); i++) {

              PdfContentByte content = pdfStamper.getOverContent(i);

              image.setAbsolutePosition(450f, 280f);
            image.setAbsolutePosition(reader.getPageSize(1).getWidth() - image.getScaledWidth(), reader.getPageSize
                (1).getHeight() - image.getScaledHeight());
              //image.setAlignment(Image.MIDDLE);
              //content.addImage(image);
            }
            pdfStamper.close();
            b = baos.toByteArray();
          }
          else{
            b = doc;
          }
          b=doc;*/
          svg ="<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + svg;
          TranscoderInput localTranscoderInput = new TranscoderInput(new StringReader(svg));
          final BufferedImage[] imagePointer = new BufferedImage[1];
            ImageTranscoder t = new ImageTranscoder() {

                @Override
                public BufferedImage createImage(int w, int h) {
                    return new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
                }

                @Override
                public void writeImage(BufferedImage image, TranscoderOutput out)
                        throws TranscoderException {
                    imagePointer[0] = image;
                }
            };
            t.transcode(localTranscoderInput, null);
            BufferedImage o = imagePointer[0];
            ByteArrayOutputStream imgb = new ByteArrayOutputStream();

          if(!type.equals("pdf")) {
            /*PDDocument document = PDDocument.load(new ByteArrayInputStream(b));
            PDFTextStripper stripper=new PDFTextStripper();
            String s=stripper.getText(document);
            System.out.println(s);
            PDPageTree pdPages = document.getDocumentCatalog().getPages();
            PDPage page = pdPages.get(0);
            BufferedImage o = new PDFRenderer(document).renderImage(0);
            ByteArrayOutputStream imgb = new ByteArrayOutputStream();*/

            String ct = "";
            String ext = "";
            if(type.equals("png")){
              ct = "image/png";
              ext = "png";
            }
            else if(type.equals("jpg")){
              ct = "image/jpg";
              ext = "jpg";
            }
            ImageIO.write(o, "png", imgb);
            byte[] outfile = imgb.toByteArray();
            if(name == null || name.equals("")){
              name = "chart";
            }
            return Response.ok(outfile).type(ct).header(
                "content-disposition",
                "attachment; filename = "+name+"." + ext).header(
                "content-length", outfile.length).build();
          }
          else{
//                PdfReader reader = new PdfReader(doc);
//                PdfStamper pdfStamper = new PdfStamper(reader,
//                    baos);
              ByteArrayOutputStream baos = new ByteArrayOutputStream();
              Image image = Image.getInstance(o, null);

              Document doc=new Document();
              doc.setPageSize(new Rectangle(image.getWidth(),image.getHeight()));
              PdfWriter writer=PdfWriter.getInstance(doc,baos);
              doc.open();

//                PdfContentByte content = pdfStamper.getOverContent(i);
              PdfContentByte content = writer.getDirectContent();

              image.setAbsolutePosition(0, 0);
              image.setAlignment(Image.MIDDLE);
              content.addImage(image);

              doc.close();
//                pdfStamper.close();
              byte[] outfile = baos.toByteArray();
            if(name == null || name.equals("")){
              name = "chart";
            }
            return Response.ok(outfile).type(converter.getContentType()).header(
                "content-disposition",
                "attachment; filename = "+name+"." + converter.getExtension()).header(
                "content-length", outfile.length).build();
          }
        } catch (Exception e) {
            log.error("Error exporting Chart to  " + type, e);
            return Response.serverError().entity(e.getMessage()).status(Status.INTERNAL_SERVER_ERROR).build();
        }
    }

  /**
   * Get the version.
   * @summary Get the Saiku version.
   * @return A String containing the current version.
   */
  public static String getVersion() {
    Properties prop = new Properties();
    InputStream input = null;
    String version = "";
    ClassLoader classloader = Thread.currentThread().getContextClassLoader();
    InputStream is = classloader.getResourceAsStream("org/saiku/web/rest/resources/version.properties");
    try {

      //input = new FileInputStream("version.properties");

      // load a properties file
      prop.load(is);

      // get the property value and print it out
      System.out.println(prop.getProperty("VERSION"));
      version = prop.getProperty("VERSION");
    } catch (IOException e) {
      e.printStackTrace();
    }
    return version;
  }
}
时间: 2024-08-07 17:49:52

Saiku图表导出时中文显示问题的解决方法的相关文章

ubuntu 中用vim打开txt等文件中文显示乱码的解决方法 &nbsp;

今晚用ubuntu 12.04 的vim编辑网页代码时,发现上面的中文显示乱码.这个html文件是我之前用gedit编辑的,在gedit里面显示正常,可是在vim下显示就是乱码了. 怎么解决ubuntu中vim显示中文乱码的问题呢? 首先,添加中文字符编码: sudo gedit /var/lib/locales/supported.d/local 在打开的文件中添加下面的中文字符集 zh_CN.GBK GBK zh_CN.GB2312 GB2312 zh_CN.GB18030 GB18030

ASP.NET中文显示乱码之解决方法

在config.web中设置globalization段 <configuration> <globalization requestEncoding="gb2312" responseEncoding="gb2312" fileEncoding="gb2312"/></configuration> 可以是utf-8.gb2312等等. ASP.NET中文显示乱码之解决方法

PLSQL Developer中文显示乱码的解决方法

PLSQL Developer中文显示乱码是因为Oracle数据库所用的编码和PLSQL Developer所用的编码不同所导致的. 解决方法: 1. 先查询Oracle所用的编码 select userenv('language') from dual; 2. 设置PLSQL 的所用编码为第1步查询得到的编码格式 新建一个环境变量:  NLS_LANG 例如: 3. 重启 PLSQL 问题得到解决

PLSQLDeveloper中文显示乱码的解决方法

PLSQL客户端打开汉字显示乱码问题 PLSQL Developer中文显示乱码是因为Oracle数据库所用的编码和PLSQL Developer所用的编码不同所导致的. 解决方法: 1. 先查询Oracle所用的编码 select userenv('language') from dual; 2. 设置PLSQL 的所用编码为第1步查询得到的编码格式 新建一个环境变量: NLS_LANG  例如: 3. 重启 PLSQL 问题得到解决

关于Tomcat/Android/JAVA交互时中文传输乱码的解决方法

最近在做项目的时候,与服务器交互传输信息时,出现中文乱码问题.由于一开始对编码这个东西不是很了解,都是一知半解状态,平时所谓的程序中的转码也都是基于侥幸的过去了,没遇到什么问题.可这次却没这么幸运了,中文乱码....,好了,废话不多说了,直入主题. 如何才能正确解码?首先要清楚的知道源数据是以什么样的编码方式encode过来的,然后再以对应的编码方式decode才能正确解码,否则就会变成乱码! 举例说吧: 以Tomcat作服务器,默认的环境编码是ios-8859-1,客户端编码方式为UTF-8(

NestedScrollView嵌套ListView时只显示一行的解决方法

在使用CoordinatorLayout和AppBarLayout实现嵌套滑动的时候,出现listview没有嵌套滑动: 如果要实现嵌套滑动,则需要添加NestedScrollView,但是结果发现listview只显示一行数据 <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent"

Linux下Eclipse中 中文显示乱码的解决方法

解决方法:在菜单项Window下打开子菜单prefence,在其中设置编码方式为UTF-8.

安装redhat时中文显示乱码(小方框)解决方法

在安装linux的时候,安装完了中文出现乱码或者是当时选错了选成了英文的,到时候中文显示乱码,下面说一下问题的解决: 在首次安装RHEL5时,如果选择的是英文,那么系统将不安装中文支持包,这样就导致了中文显示为乱码(小方框)....... 有很多人说vi /etc/sysconfig/i18n文件,其实根本就没有那个必要. 解决方法: 安装 1.fonts-chinese-3.02-9.6.el5.noarch.rpm.  如果无法安装,则加个--force 2.fonts-ISO8859-2-

get/post时中文乱码问题的解决办法

常有的方法,get请求用在tomcat的编码改为utf-8 即可 post 过滤器就可以 一.常识了解 1.GBK包含GB2312,即如果通过GB2312编码后可以通过GBK解码,反之可能不成立; 2.java.nio.charset.Charset.defaultCharset() 获得平台默认字符编码: 3.getBytes() 是通过平台默认字符集进行编码: 二.中文乱码出现 在学习任何一门技术时,经常会有初学者遇到中文乱码问题,比如MySQL,是因为在安装时没有设置:而在Servlet中