(原创)Java 读取 Highcharts 中的图片

前言:项目中提出一个新需求,就将Highcharts中的图片读取到Excel中。并在前台做下载,当听到这功能,第一想法是需要由后台编写程序,将数据写道图片中。

虽然没做过但是也没觉得太难,毕竟前辈们肯定也做过类似的功能。但是后来发现Highcharts本身就可以导出图片,也能导出不同格式图片。

我突然觉得将Highcharts的图片流传到后台,在输出到Excel中不就可以了吗?于是开始了.....

第一步:首先要获取Highcharts中SVG对象,信息保存到 form表单中。

第二步:将SVG 转换成PNG格式

 别问我为什么,因为报错!报错!报错... 不能直接解析SVG

所需要jar包

batik-all-1.7.jar

batik-transcoder-1.7.jar

xml-apis-ext-1.3.04.jar

链接: https://pan.baidu.com/s/1FkLvC7dnXdLla5FASpjEKw 提取码: 71aq 复制这段内容后打开百度网盘手机App,操作更方便哦

下面这段代码在网上找的,我能用,也就贴出来了

/**
	 * @Description: 将svgCode转换成png文件,直接输出到流中
	 * @Author:saiSQ
	 * @Since: 2013-11-4下午01:37:56
	 * @param svgCode
	 *            svg代码
	 * @param outputStream
	 *            输出流
	 *             异常
	 * @throws IOException
	 *             io异常
	 */
	public static void convertToPng(String svgCode, OutputStream outputStream){
		try {
			byte[] bytes = svgCode.getBytes("UTF-8");

			PNGTranscoder t = new PNGTranscoder();
			t.addTranscodingHint(PNGTranscoder.KEY_WIDTH, new Float(1024));//只要指定宽度即可,高度自动调整。
			TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(bytes));
			TranscoderOutput output = new TranscoderOutput(outputStream);
			t.transcode(input, output);
			outputStream.flush();
		}catch (Exception e){
			e.printStackTrace();
		}finally {
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

  第三步:将文件写入response 中,做页面下载(以上是我写的代码,安全起见,我复制下来时,删掉了部分代码,如果没有运行成功,下方留言,按照你的情况再做解答,这里只说个思路。勿怪,勿怪)

/**
     * 生成Excel 文档
     */
    @RequestMapping(value = "/downExcel",produces = "application/json;charset=UTF-8")
    public void createdExcel(HttpServletRequest request, HttpServletResponse response){
            ByteArrayOutputStream byteArrayOut=null;
            HSSFWorkbook wb=null;
            OutputStream os=null;
            String svgCode=request.getParameter("svg");
try {
                //加载图片
                byteArrayOut= new ByteArrayOutputStream();
                convertToPng(svgCode,byteArrayOut);
                //加载图片
                wb= new HSSFWorkbook();
                HSSFSheet sheet1 = wb.createSheet("sheet1");
                HSSFPatriarch patriarch = sheet1.createDrawingPatriarch();
                /**
                 dx1 - the x coordinate within the first cell.//定义了图片在第一个cell内的偏移x坐标,既左上角所在cell的偏移x坐标,一般可设0
                 dy1 - the y coordinate within the first cell.//定义了图片在第一个cell的偏移y坐标,既左上角所在cell的偏移y坐标,一般可设0
                 dx2 - the x coordinate within the second cell.//定义了图片在第二个cell的偏移x坐标,既右下角所在cell的偏移x坐标,一般可设0
                 dy2 - the y coordinate within the second cell.//定义了图片在第二个cell的偏移y坐标,既右下角所在cell的偏移y坐标,一般可设0
                 col1 - the column (0 based) of the first cell.//第一个cell所在列,既图片左上角所在列
                 row1 - the row (0 based) of the first cell.//图片左上角所在行
                 col2 - the column (0 based) of the second cell.//图片右下角所在列
                 row2 - the row (0 based) of the second cell.//图片右下角所在行
                 */
                int line=23;//
                int row=12;//行exportProjectExcel
                HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0,(short) 0, 0, (short) row, line);
                //插入图片
                patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG));                //再图片下插入内容
                HSSFRow hssfRow=null;
                HSSFCell hssfCell=null;
                String fileName = "xxxx名称.xls";// 文件名
                setResponseHeader(response,fileName);
                os=response.getOutputStream();
                // 输出文件
                wb.write(os);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try{
                    if(byteArrayOut!=null){
                        byteArrayOut.close();
                    }
                    if(byteArrayOut!=null){
                        byteArrayOut.close();
                    }
                    if(wb!=null){
                        wb.close();
                    }
                    if(os!=null){
                        os.close();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
    }

第四步:测试效果

浏览器

Excel

五:特别注意: Highcharts 导出来的图片有可能因为比例问题,会导致数据出现问题,需要修改一下 Highcharts 宽度即可

这是前端大佬写的,我也不太懂,大概意思就是初始化 Highcharts表的时候 修改他的宽度, (svg_width 这里设置成了全量,获取的是浏览器上显示Highcharts那一快区域的宽度。主要是不能设置成百分比,写死了又不好)

Highcharts.chart('container', {
chart: {
type: 'column',
width: svg_width
},

 

到此该功能基本能实现出来了,别看简单,花了我两天时间,在快要崩溃的时候,出现了奇迹。

posted @ 2019-04-17 10:58  不朽_张  阅读(641)  评论(1编辑  收藏  举报