Highcharts是一款優秀的圖表圖形工具,支持幾乎所有的圖表圖形,相信很多朋友都在項目中使用過該組件,然而我想我們不僅僅是要用它做展示還要講分析出來的圖表進行導出(word或pdf),本人最近的項目就遇到了這樣的一個問題,需要將highcharts生成的圖表導出到word和pdf中,于是我就簡單的研究了一下,下面是我做的一個Demo;
導出word那一部分我就不多講了,不了解的可以參考我的前一篇文章(http://blog.csdn.net/zwx19921215/article/details/34439851)
相關jar包下載地址:http://download.csdn.net/detail/zwx19921215/8368135
同樣是一個SpringMvc的project
svg轉換為圖片工具類(png)
package com.tgb.util;import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;/***@Description: 將svg轉換為png格式的圖片*/
public class SvgPngConverter {/***@Description: 將svg字符串轉換為png*@Author:*@param svgCode svg代碼*@param pngFilePath 保存的路徑*@throws IOException io異常*@throws TranscoderException svg代碼異常*/public static void convertToPng(String svgCode,String pngFilePath) throws IOException,TranscoderException{File file = new File (pngFilePath);FileOutputStream outputStream = null;try {file.createNewFile ();outputStream = new FileOutputStream (file);convertToPng (svgCode, outputStream);} finally {if (outputStream != null) {try {outputStream.close ();} catch (IOException e) {e.printStackTrace ();}}}}/***@Description: 將svgCode轉換成png文件,直接輸出到流中*@param svgCode svg代碼*@param outputStream 輸出流*@throws TranscoderException 異常*@throws IOException io異常*/public static void convertToPng(String svgCode,OutputStream outputStream) throws TranscoderException,IOException{try {byte[] bytes = svgCode.getBytes ("UTF-8");PNGTranscoder t = new PNGTranscoder ();TranscoderInput input = new TranscoderInput (new ByteArrayInputStream (bytes));TranscoderOutput output = new TranscoderOutput (outputStream);t.transcode (input, output);outputStream.flush ();} finally {if (outputStream != null) {try {outputStream.close ();} catch (IOException e) {e.printStackTrace ();}}}}
}
IText操作word和pdf工具類
package com.tgb.util;import java.awt.Color;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.rtf.RtfWriter2;
import com.tgb.entity.News;/*** IText操作類* @author shyh**/
public class ItextManager {private Font font;private BaseFont bfChinese;public ItextManager() throws Exception {// 設置中文字體bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);font = new Font(bfChinese);font.setSize(15);font.setStyle(FontFactory.HELVETICA);
// font.setStyle(Font.BOLD);//加粗font.setColor(new Color(0,0,0));}public static ItextManager getInstance() throws Exception {return new ItextManager();}public void createRtfContext(List<News> newsList, List<String> imgList, OutputStream out,String type) {Document doc = new Document(PageSize.A4, 20, 20, 20, 20);try {if("word".equals(type)){RtfWriter2.getInstance(doc, out);}else if("pdf".equals(type)){PdfWriter.getInstance(doc, out);}doc.open();News news = null;Paragraph title1 = null;for (int i = 0; i < newsList.size(); i++) {news = newsList.get(i);// 標題Paragraph title = new Paragraph(news.getTitle(), font);title.setAlignment(Element.ALIGN_LEFT);doc.add(title);// 換行title1 = new Paragraph("\n");doc.add(title1);// 正文Paragraph content = new Paragraph(news.getContent(), font);content.setAlignment(Element.ALIGN_LEFT);doc.add(content);// 換行title1 = new Paragraph("\n");doc.add(title1);// 站點Paragraph site = new Paragraph(news.getSite(), font);content.setAlignment(Element.ALIGN_LEFT);doc.add(site);// 換行title1 = new Paragraph("\n");doc.add(title1);// 發布時間Paragraph publishTime = new Paragraph(news.getPublishTime(), font);content.setAlignment(Element.ALIGN_LEFT);doc.add(publishTime);// 換行title1 = new Paragraph("\n");doc.add(title1);}Image img = null;for (int j = 0; j < imgList.size(); j++) {// 圖片img = Image.getInstance(imgList.get(j));float heigth = img.getHeight();float width = img.getWidth();int percent = getPercent2(heigth, width);img.setAlignment(Image.MIDDLE);img.scalePercent(percent + 3);// 表示是原來圖像的比例;doc.add(img);}doc.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (DocumentException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/*** 第一種解決方案 在不改變圖片形狀的同時,判斷,如果h>w,則按h壓縮,否則在w>h或w=h的情況下,按寬度壓縮* * @param h* @param w* @return*/public static int getPercent(float h, float w) {int p = 0;float p2 = 0.0f;if (h > w) {p2 = 297 / h * 100;} else {p2 = 210 / w * 100;}p = Math.round(p2);return p;}/*** 第二種解決方案,統一按照寬度壓縮 這樣來的效果是,所有圖片的寬度是相等的,自我認為給客戶的效果是最好的* * @param args*/public static int getPercent2(float h, float w) {int p = 0;float p2 = 0.0f;p2 = 530 / w * 100;p = Math.round(p2);return p;}
}
控制層:
@RequestMapping(value="/exportword")public String exportWord(HttpServletRequest request,HttpServletResponse response) throws Exception{String type = request.getParameter("type");response.setContentType("application/octet-stream; charset=UTF-8"); if("word".equals(type)){response.setHeader("content-disposition", "attachment;filename=" + new SimpleDateFormat("yyyyMMddHH:mm:ss").format(new Date()) + ".doc");}else if("pdf".equals(type)){response.setHeader("content-disposition", "attachment;filename=" + new SimpleDateFormat("yyyyMMddHH:mm:ss").format(new Date()) + ".pdf");}String svgCode = request.getParameter("svg");//highcharts圖表svgCodeString svg [] = svgCode.split("_");String path[] = new String[svg.length];OutputStream out = response.getOutputStream();ItextManager tm = ItextManager.getInstance();List<News> newsList = userService.getData();List<String> imageList = new ArrayList<String>();if(svg!=null){for(int k=0;k<svg.length;k++){String picName = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date())+".png";path[k] = request.getSession().getServletContext().getRealPath("/upload/"+picName);imageList.add(path[k]);SvgPngConverter.convertToPng(svg[k], path[k]);}}tm.createRtfContext(newsList,imageList,out,type);out.flush();out.close();return null;}
注意:我的svg是一個數組,因為我有多個圖表,而且我首先將svg轉換成圖片然后存儲到如下路徑:
path[k] = request.getSession().getServletContext().getRealPath("/upload/"+picName);最后,將圖片寫入到word中(圖片數組):
tm.createRtfContext(newsList,imageList,out,type);
業務層
@Overridepublic List<News> getData() {List<News> newsList = new ArrayList<News>();News news1 = new News();news1.setTitle("標題:國泰君安*公司研究*廣發證券:定增完成,如虎添翼*000776*投資銀行業與經紀業行業*梁靜");news1.setContent("正文:報告類型=公司事件點評公司簡稱=廣發證券公司代碼=000776報告日期=Thu Aug 25 09:05:29 CST 2011研究員 =梁靜報告標題=定增完成,如虎添翼【報告摘要】8月25日,廣發證券成功向揭陽市信宏資產、匯添富基金、上海海博鑫惠、興業基金等10家機構定向增發4.526億股、募集資金121.8億元,募集資金凈額120億元。");news1.setSite("站點:新浪網");news1.setPublishTime("發布時間:2014-05-12");News news2 = new News();news2.setTitle("標題:[申萬銷售夏敬慧] 基金倉位周報----開基倉位下降1.51%");news2.setContent("正文:理財產品部分析師: 楊鵬(18930809297) 開基倉位有所下降:本周,開放式基金平均倉位繼續下降。");news2.setSite("站點:騰訊網");news2.setPublishTime("發布時間:2014-05-25");newsList.add(news1);newsList.add(news2);return newsList;}
展示層
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>導出word</title>
<script type="text/javascript" src="js/jquery/jquery-1.7.1.js"></script>
<script src="js/highcharts/4.0.1/js/highcharts.js"></script>
<script src="js/highcharts/4.0.1/js/modules/exporting.js"></script>
<script type="text/javascript">$(function() {Highcharts.wrap(Highcharts.Chart.prototype, 'getSVG', function (proceed) {return proceed.call(this).replace(/(fill|stroke)="rgba\(([ 0-9]+,[ 0-9]+,[ 0-9]+),([ 0-9\.]+)\)"/g, '$1="rgb($2)" $1-opacity="$3"');});$('#container').highcharts({title : {text : 'Monthly Average Temperature',x : -20//center},subtitle : {text : 'Source: WorldClimate.com',x : -20},xAxis : {categories : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]},yAxis : {title : {text : 'Temperature (°C)'},plotLines : [ {value : 0,width : 1,color : '#808080'} ]},tooltip : {valueSuffix : '°C'},legend : {layout : 'vertical',align : 'right',verticalAlign : 'middle',borderWidth : 0},series : [ {name : 'Tokyo',data : [ 7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6 ]}, {name : 'New York',data : [ -0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5 ]}, {name : 'Berlin',data : [ -0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0 ]}, {name : 'London',data : [ 3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8 ]} ]});$('#container_pie').highcharts({chart : {plotBackgroundColor : null,plotBorderWidth : null,plotShadow : false},title : {text : 'Browser market shares at a specific website, 2010'},tooltip : {pointFormat : '{series.name}: <b>{point.percentage:.1f}%</b>'},plotOptions : {pie : {allowPointSelect : true,cursor : 'pointer',dataLabels : {enabled : true,color : '#000000',connectorColor : '#000000',format : '<b>{point.name}</b>: {point.percentage:.1f} %'}}},series : [ {type : 'pie',name : 'Browser share',data : [ [ 'Firefox', 45.0 ], [ 'IE', 26.8 ], {name : 'Chrome',y : 12.8,sliced : true,selected : true}, [ 'Safari', 8.5 ], [ 'Opera', 6.2 ], [ 'Others', 0.7 ] ]} ]});});
</script>
<script type="text/javascript">function exportHighcharts(type){var chart_line = $("#container").highcharts();var chart_pie = $("#container_pie").highcharts();var svg_line = chart_line.getSVG();var svg_pie = chart_pie.getSVG();var svg = svg_line+"_"+svg_pie;$("#svg").val(svg);$("#form1").prop("action", "exportword.do?type="+type+"").submit();}
</script>
</head>
<body><form id="form1" action="exportword.do" method="post"><div><input type="hidden" name="svg" id="svg" /> <input id="btn_word" type="button" value="導出word" οnclick="exportHighcharts('word');"/> <input id="btn_pdf" type="button" value="導出pdf" οnclick="exportHighcharts('pdf');"/></div></form><div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div><div id="container_pie" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
</html>
總結
以上是生活随笔為你收集整理的Java通过HighCharts导出图表的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。