highCharts 轉svg 導出excel
阿新 • • 發佈:2018-05-10
highCharts svg excel 具體的需求是這樣的:
前臺要將查出來的數據用highcharts 展示,包括數據封裝到table中,table 中展示hightchart的圖標,例如這樣
這個應該不難實現,那麽這個頁面下面有一個導出按鈕,要將這些數據(table +hightcharts 的圖標)到處成excel 到本地,問題是怎麽將hightcharts 顯示在excel中,理論上報圖標保存為圖片,在workbook中調用圖片也不難,但是現在需要點導出的時候就要生成excel ,這就有點復雜。
具體點的實現是這樣的:在前臺將highchart的數據生成svg ,在後臺將svg 在生成字節流,然後將字節流寫到workbook 中。
代碼如下
前臺的hightcharts 是這樣的:
var dailyChartObjOption = { chart: { renderTo: 'div_survey', margin: [ 50, 10, 40,10], polar: true, type: 'line' }, title: { text: ("網發調研"), floating: true, style: { fontFamily: '上海大眾l,Microsoft YaHei, Verdana, Arial',minWidth:'1170px',fontSize:'16px'} }, pane: { size: '100%' }, xAxis: { categories:['<%=EnumSurveyType.SQS.getName() %>','<%=EnumSurveyType.CSS.getName() %>','<%=EnumSurveyType.MS.getName() %>','<%=EnumSurveyType.OIC.getName() %>','<%=EnumSurveyType.DCDA.getName() %>'], labels: { style: { fontFamily: 'xxxx,Microsoft YaHei, Verdana, Arial',minWidth:'1170px' } }, tickmarkPlacement: 'on', lineWidth: 0 }, yAxis: { min: 0, max:100, labels: { enabled:false, style: { fontFamily: 'xxxx,Microsoft YaHei, Verdana, Arial',minWidth:'1170px' } } }, tooltip: { valueSuffix: '', style: { fontFamily: 'xxxxx,Microsoft YaHei, Verdana, Arial',minWidth:'1170px'}, formatter: function() { var y = this.y; if (this.x == "<%=EnumSurveyType.SQS.getName() %>") { y = Math.round(parseFloat(this.y) * 1000)/100; } else if(this.x == "<%=EnumSurveyType.DCDA.getName() %>"){ if (this.series.name == "區域平均") { y = Math.round(parseFloat(${dcnAvgScore}) * 100)/100; } else if (this.series.name == "區域最優") { y = Math.round(parseFloat(${dcnTopScore}) * 100)/100; } else{ y = Math.round(parseFloat(${dcnScore}) * 100)/100; } } var color_this = color; if (this.series.name == "區域平均") { color_this = colorAvg; } else if (this.series.name == "區域最優") { color_this = colorTop; } return '<span style="color:'+ color_this +';">' + this.x + '</span><span>:</span><b>' + y + '</b>'; } }, exporting: { enabled: false }, credits: { enabled: false }, margin: [0, 0, 0, 0], backgroundColor: "#FFF", series: [{ pointPlacement: 'on', color:colorAvg, name:"區域平均", data: [${sqsAvgScore},${qsssAvgScore},${msAvgScore},${hicAvgScore},${dcnAvgScore}/8] },{ pointPlacement: 'on', color:colorTop, name:"區域最優", data: [${sqsTopScore},${qsssTopScore},${msTopScore},${hicTopScore},${dcnTopScore}/8] },{dataLabels: { enabled: true }, pointPlacement: 'on', color:color, name:"${dealerBase.nickName}", data: [${sqsScore},${qsssScore},${msScore},${hicScore},${dcnScore}/8] }], plotOptions: { line: { marker: { radius: 3 }, dataLabels: { enabled:false, formatter: function() { var y = this.y; if (this.x == "<%=EnumSurveyType.SQS.getName() %>") { y = Math.round(parseFloat(this.y) * 1000)/100; } else if(this.x == "<%=EnumSurveyType.DCDA.getName() %>"){ y = Math.round(parseFloat(this.y) * 800)/100; } return y ; }, style: { fontFamily: 'xxxx,Microsoft YaHei, Verdana, Arial',minWidth:'1170px'} }, enableMouseTracking: true } }, legend: { enabled :true, itemWidth:itemWidth, borderWidth:0, y:5, style: { fontFamily: 'xxxxx,Microsoft YaHei, Verdana, Arial',minWidth:'1170px'} } }; var dailyChartObjOptionEn = { chart: { renderTo: 'div_survey_en', margin: [ 50, 10, 40,10], polar: true, type: 'line' }, title: { text: ("SKN Survey"), floating: true, style: { fontFamily: 'xxxxx,Microsoft YaHei, Verdana, Arial',minWidth:'1170px',fontSize:'16px'} }, pane: { size: '100%' }, xAxis: { categories:['<%=EnumSurveyType.SQS.getName() %>','<%=EnumSurveyType.CSS.getName() %>','<%=EnumSurveyType.MS.getName() %>','<%=EnumSurveyType.OIC.getName() %>','<%=EnumSurveyType.DCDA.getName() %>'], labels: { style: { fontFamily: 'xxxxx,Microsoft YaHei, Verdana, Arial',minWidth:'1170px' } }, tickmarkPlacement: 'on', lineWidth: 0 }, yAxis: { min: 0, max:100, labels: { enabled:false, style: { fontFamily: 'xxxx,Microsoft YaHei, Verdana, Arial',minWidth:'1170px' } } }, tooltip: { valueSuffix: '', style: { fontFamily: 'xxxx,Microsoft YaHei, Verdana, Arial',minWidth:'1170px'}, formatter: function() { var y = this.y; if (this.x == "<%=EnumSurveyType.SQS.getName() %>") { y = Math.round(parseFloat(this.y) * 1000)/100; } else if(this.x == "<%=EnumSurveyType.DCDA.getName() %>"){ if (this.series.name == "Average") { y = Math.round(parseFloat(${dcnAvgScore}) * 100)/100; } else if (this.series.name == "Best") { y = Math.round(parseFloat(${dcnTopScore}) * 100)/100; } else{ y = Math.round(parseFloat(${dcnScore}) * 100)/100; } } var color_this = color; if (this.series.name == "Average") { color_this = colorAvg; } else if (this.series.name == "Best") { color_this = colorTop; } return '<span style="color:'+ color_this +';">' + this.x + '</span><span>:</span><b>' + y + '</b>'; } }, exporting: { enabled: false }, credits: { enabled: false }, margin: [0, 0, 0, 0], backgroundColor: "#FFF", series: [{ pointPlacement: 'on', color:colorAvg, name:"Average", data: [${sqsAvgScore},${qsssAvgScore},${msAvgScore},${hicAvgScore},${dcnAvgScore}/8] },{ pointPlacement: 'on', color:colorTop, name:"Best", data: [${sqsTopScore},${qsssTopScore},${msTopScore},${hicScore},${dcnTopScore}/8] },{dataLabels: { enabled: true }, pointPlacement: 'on', color:color, name:"${dealerBase.nickNameEn}", data: [${sqsScore},${qsssScore},${msScore},${hicScore},${dcnScore}/8] }], plotOptions: { line: { marker: { radius: 3 }, dataLabels: { enabled:false, formatter: function() { var y = this.y; if (this.x == "<%=EnumSurveyType.SQS.getName() %>") { y = Math.round(parseFloat(this.y) * 1000)/100; } else if(this.x == "<%=EnumSurveyType.DCDA.getName() %>"){ y = Math.round(parseFloat(this.y) * 800)/100; } return y ; }, style: { fontFamily: 'xxxx,Microsoft YaHei, Verdana, Arial',minWidth:'1170px'} }, enableMouseTracking: true } }, legend: { enabled :true, itemWidth:itemWidth, borderWidth:0, y:5, style: { fontFamily: 'xxx,Microsoft YaHei, Verdana, Arial',minWidth:'1170px'} } };
然後在ajax 中將圖標轉成svg
RadaObj = new Highcharts.Chart(dailyChartObjOption); RadaObjSVG = RadaObj.getSVG();
後臺接收是這樣子的
HSSFPatriarch patriarch = (HSSFPatriarch) chineseSheet.createDrawingPatriarch(); // 2進制流 // 零售銷量 if (!StringUtils.isEmpty(retailSalesObjSvg)) { retailSalesOut = rasterizer.transcode(new ByteArrayOutputStream(), retailSalesObjSvg, MimeType.PNG, null); // 零售銷量 HSSFClientAnchor anchorOne = new HSSFClientAnchor(100, 50, 923, 205, (short) 9, (short) 15, (short) 12, (short) 17); patriarch.createPicture(anchorOne, wb.addPicture(retailSalesOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG)); }
SvgRasterizer svg 轉換的公共類
public class SvgRasterizer { /** * <p> * Description: * </p> * Field INSTANCE:INSTANCE */ private static final SvgRasterizer INSTANCE = new SvgRasterizer(); public static final SvgRasterizer getInstance() { return INSTANCE; } /** * <p> * Description:svg轉換 * </p> * * @param stream 流 * @param svg svg字符串 * @param mime mime類型 * @param width 寬度 * @return ByteArrayOutputStream 返回值 * @throws SvgRasterizerException 異常 * @throws TranscoderException 異常 * @throws UnsupportedEncodingException 異常 */ public synchronized ByteArrayOutputStream transcode(ByteArrayOutputStream stream, String svg, MimeType mime, Float width) throws SvgRasterizerException, TranscoderException, UnsupportedEncodingException { //TranscoderInput input = new TranscoderInput(new StringReader(svg)); TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(svg.getBytes("utf-8"))); TranscoderOutput transOutput = new TranscoderOutput(stream); SVGAbstractTranscoder transcoder = getTranscoder(mime); if (width != null) { transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, width); } transcoder.transcode(input, transOutput); return stream; } /** * <p> * Description:獲取轉換器 * </p> * * @param mime mime類型 * @return SVGAbstractTranscoder 返回值 * @throws SvgRasterizerException 異常 */ public static SVGAbstractTranscoder getTranscoder(MimeType mime) throws SvgRasterizerException { SVGAbstractTranscoder transcoder = null; switch (mime.ordinal()) { case 0: transcoder = new PNGTranscoder(); break; case 1: transcoder = new JPEGTranscoder(); transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, new Float(0.9D)); break; case 2: transcoder = new PDFTranscoder(); break; default: break; } if (transcoder == null) { throw new SvgRasterizerException("MimeType not supported"); } return transcoder; } }
這樣就可以了
highCharts 轉svg 導出excel