Echart图生成pdf

7 篇文章 0 订阅
5 篇文章 0 订阅

最近要实现打印echart图的功能,echart图自带的是生成图片,研究了一下,在这总结一下,总共有两种方式:

  • 第一种:前台直接打印,不走服务器端,原理是扫描html页面生成图片流再生成pdf,弊端是ie浏览器不能用
  • 第二种:获取echarts图的base64编码,通过后台生成图片,再生成pdf

第一种前台直接打印:

需要引入的包html2canvas.js和jsPdf.debug.js。我所打印的页面是不需要分页的,大家自行选择,注释部分的代码为测试代码,请斟酌后再使用。

//导出
    $("#exportImg").click(function ()  {
        var target = document.getElementById("test");//需要打印区域的id
        target.style.background = "#FFFFFF";//设置打印背景的颜色为白色,若不设置,会发现背景为黑色
            html2canvas(target, {
                onrendered:function(canvas) {
                    //返回图片URL,参数:图片格式和清晰度(0-1)
                    var pageData = canvas.toDataURL('image/jpeg', 1.0);
                    //方向默认竖直,尺寸ponits,格式a4【595.28,841.89]
                    var pdf = new jsPDF('', 'pt', 'a4');
                    //需要dataUrl格式
                    //arg3-->距离左边距;arg4-->距离上边距;arg5-->宽度;arg6-->高度
                    pdf.addImage(pageData, 'JPEG', 20, 20, 595.28, 592.28/canvas.width * canvas.height );
                    pdf.save('echart图.pdf');
                }
            })
           /* html2canvas(document.getElementById('zbChart'), {
                onrendered: function(canvas) {
                    document.body.appendChild(canvas);
                    createPDFObject(canvas.toDataURL("image/jpeg"));
                }
            });*/

        /*html2canvas(target, {
            onrendered:function(canvas) {
                var contentWidth = canvas.width;
                var contentHeight = canvas.height;

                //一页pdf显示html页面生成的canvas高度;
                var pageHeight = contentWidth / 592.28 * 841.89;
                //未生成pdf的html页面高度
                var leftHeight = contentHeight;
                //页面偏移
                var position = 0;
                //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
                var imgWidth = 595.28;
                var imgHeight = 592.28/contentWidth * contentHeight;
                var pageData = canvas.toDataURL('image/jpeg', 1.0);
                var pdf = new jsPDF('', 'pt', 'a4');
                //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
                //当内容未超过pdf一页显示的范围,无需分页
                if (leftHeight < pageHeight) {
                    pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight );
                } else {
                    while(leftHeight > 0) {
                        pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
                        leftHeight -= pageHeight;
                        position -= 841.89;
                        //避免添加空白页
                        if(leftHeight > 0) {
                            pdf.addPage();
                        }
                    }
                }
                pdf.save("content.pdf");
            }
        })
    });
    function createPDFObject(imgData) {
        var doc = new jsPDF('p', 'pt');
        // 修改背景色
        $('#test').css("background", "#fff")
        doc.addImage(imgData, 5, 5, 600, 300, 'img');
        doc.save('echart图'  + '.pdf')
    }*/

第二种:走后台服务端

因生成图片编码会很长,用window.open会报请求头过长的错误,虽然这个错误可通过修改tomcat中server.xml文件来解决,本人亲测,修改后会导致部分请求不好用,建议不用。所以在这里用form表单请求提交后台,用form表单时如果想新跳转一个窗口,需添加target="_black",否则是在本窗口显示。ie9浏览器初次加载时会不好用,但是多次重新加载后会好用,此问题尚未发现原因。

  • html页面代码:
<form id="chartForm" style="display:none" target="_blank">
    <input id="pdfTitle" name="pdfTitle" type="text" maxlength="100"/>
    <input id="imageValue" name="base64Info" type="text" maxlength="50000"/>
</form>
  • js代码:
$('#exportImg').click(function(){
        var chartExportUrl = '../echartImg/export.htm';
        var thisChart = echarts.init(document.getElementById('zbChart'));
        var picBase64Info = thisChart.getDataURL();//获取echarts图的base64编码,为png格式。
        exportImg(chartExportUrl,picBase64Info,"echart图");
    });
function exportImg(chartExportUrl,picBase64Info,title){
    $('#chartForm').find('input[name="base64Info"]').val(picBase64Info);//将编码赋值给输入框
    $('#chartForm').find('input[name="pdfTitle"]').val(title);//将标题赋值给输入框
    $('#chartForm').attr('action',chartExportUrl).attr('method', 'post');//设置提交到的url地址
    $('#chartForm').attr('action',chartExportUrl).attr('method', 'post');//设置提交方式为post
    $('#chartForm').submit();
    // window.open(chartExportUrl+"?base64Info="+picBase64Info);请求头太长,只能用form提交
}
  • 后台代码:此处只展示工具类,控制类请自己写
 public static String exportFilePath = "D:/image/";

    //echart图生成图片,所以需要在服务器新建一个文件夹来存放
    public static void exportImg(HttpServletResponse response,String base64Info,String pdfTitle){
        String newFileName = pdfTitle + System.currentTimeMillis() + ".pdf";
        String newPngName = newFileName.replaceFirst(".pdf", ".png");
        base64Info = base64Info.replaceAll(" ", "+");
        BASE64Decoder decoder = new BASE64Decoder();
        String[] arr = base64Info.split("base64,");
        byte[] buffer;
        try {
            buffer = decoder.decodeBuffer(arr[1]);
        } catch (IOException e) {
            throw new RuntimeException();
        }
        OutputStream output = null;
        try {
            output = new FileOutputStream(new File(exportFilePath+newPngName));//生成png文件
            output.write(buffer);
            output.flush();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
     printPdf(response,exportFilePath+newPngName,exportFilePath+newFileName,pdfTitle);
    }

    //通过png文件来生成pdf文件
    public static void printPdf(HttpServletResponse response, String imagePath, String mOutputPdfFileName, String pdfTitle) {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        Document doc = new Document(PageSize.A4, 20, 20, 20, 20);
        try {
            PdfWriter.getInstance(doc, buffer);
            Font font = PrintPdfUtil.createFont("宋体",14);
            //用table添加,可以直接添加到doc文档中,但是标题和图上下距离太远,设置间距也不管用,所以用的table
            PdfPTable table = new PdfPTable(1);//1列
            table.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getDefaultCell().setBorderWidth(0);
            table.setWidthPercentage(100);//宽度百分百
            doc.addTitle(pdfTitle);
            doc.open();
            doc.newPage();
            Image png = Image.getInstance(imagePath);
            float heigth = png.getHeight();
            float width = png.getWidth();
            int percent = getPercent2(heigth, width);
            png.setAlignment(Image.MIDDLE);//图像居中显示
            png.setAlignment(Image.TEXTWRAP);//文字围绕图像
            png.scalePercent(percent + 3);//表示是原来图像的比例
            Paragraph title = new Paragraph(pdfTitle,font);
            title.setAlignment(Paragraph.ALIGN_CENTER);
            PdfPCell cell = new PdfPCell(title);
            cell = createCell(cell);
            cell.setFixedHeight(30);//行高
            table.addCell(cell);
            PdfPCell cellImg = new PdfPCell(png);
            cellImg = createCell(cellImg);
            table.addCell(cellImg);
            doc.add(table);
            doc.close();
            //开始打印
            PrintPdfUtil.printUtil(response, buffer);
            response.setContentType("application/octet-stream");
           /* 此处注释的代码为下载,我所做的效果是生成预览pdf文件,若需下载,请用下面的
            InputStream input = null;   
            OutputStream outputString = null;
            try {
                response.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode(pdfTitle + ".pdf", "UTF-8"));
                input = new BufferedInputStream(new FileInputStream(new File(mOutputPdfFileName)));
                outputString = new BufferedOutputStream(response.getOutputStream());
                copy(input, outputString);
                outputString.flush();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }catch (IOException e) {
                e.printStackTrace();
            }finally{
                input.close();
                outputString.close();
            }*/
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static PdfPCell createCell(PdfPCell cell) throws DocumentException, IOException {
        //设置垂直居中
        cell.setUseAscender(true);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setBorderWidth(0);
        return cell;
    }
   //按照宽度压缩,呈现最好视觉效果
    private static int getPercent2(float h, float w) {
        int p = 0;
        float p2 = 0.0f;
        p2 = 530 / w * 100;
        p = Math.round(p2);
        return p;
    }
    //输入流读取到输出流
    public static void copy(InputStream input, OutputStream outputString) throws IOException {
        byte [] but = new byte[input.available()];
        try {
            while(input.read()!=-1){
                int by = input.read(but);
                outputString.write(but, 0, by);
                outputString.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
// 打印到页面预览     
    public static void printUtil(HttpServletResponse response, ByteArrayOutputStream buffer) throws IOException {
        response.reset();
        response.setContentType("application/pdf");
        DataOutput output = new DataOutputStream(response.getOutputStream());
        byte[] bytes = buffer.toByteArray();
        response.setContentLength(bytes.length);
        for (int j = 0; j < bytes.length; j++) {
            output.writeByte(bytes[j]);
        }
    }

 

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值