Java后台phantomjs导出复杂图表PDF

当前导出PDF工具

java后端如何导出像前端用echarts那么漂亮而且还有带有图表的PDF呢,或者图片。目前后端导出word或者excel都是有县城的jar,导出简单的图表也有的简单的jfreechart

总结一下用java生成PDF的方法:
A、itext-PdfStamper pdfStamper(俗称抠模板):代码简单 模板要先提供,且字段长度固定、不灵活
B、itext-Document document(正常代码撰写):模板可根据代码调整、但样式不如C灵活 要维护的后台代码较多,整个过程全手工代码插入表格
C、wkhtmltopdf(使用工具):模板样式可根据前端随意调整,要维护的前台代码较多,原理是后端命令行启动无窗webkit,中文需要依赖字体库,html渲染完成后导出文件,
D、phantomjs和C类似,只是它的侧重点除了导出文件,还可以通过webkit执行js脚本,进行定制化操作,但是目前已经不再更新,一般用于爬虫python中较多。

C,D的原理相同都是使用了webkit渲染html后导出文件

需要依赖的jar和参考文档

A/B: itext-pdfa-5.5.6.jar、itext-xtra-5.5.6.jar、itext-5.5.6.jar、itext-asian.jar 简单模板和表格
C: wkhtmltopdf-0.12.4、python2.7.14、pdfkit 参考文档:https://www.jianshu.com/p/4d65857ffe5e/

wkhtmltopdf --page-height 420mm --page-width 297mm /path/src/edit.html /path/src/edit.pdf

D:https://phantomjs.org/download

#可以直接命令行执行js脚本
phantomjs -v 

phantomjs导出PDF

流程如下

  • 编写html文件
  • 编写phantomjs 的js脚本,主要是打开该文件,并导出图片或者PDF
  • 命令行执行没问题后,可以在Java中执行cmd命令
/***
 * echarts-convert.js
 * https://phantomjs.org/download
 * https://echarts.apache.org/zh/builder.html
 *官网下载http://phantomjs.org/download.html 国内镜像http://npm.taobao.org/dist/phantomjs/
 * EChartsConvert: eharts to PDF
 *auhtor :[email protected]
 *time:2020-12-31 14:26
 */


var system = require('system');
var fs = require('fs');
var config = {
    
    
    // define the location of js files
    VUE: 'vue.min.js',
    JQUERY: 'jquery-1.9.1.min.js',
    ECHARTS: 'echarts.min.js',
    DEEPBLUE: 'deepblue.js',
    DEFAULT_WIDTH: '740',
    DEFAULT_HEIGHT: 'auto'
}, parseParams, render;


var webPage = require('webpage');
var page = webPage.create();

page.viewportSize = {
    
     width: 640,height: 768 };
// page.paperSize = {
    
    format: 'A4', orientation: 'portrait',width: '740px', height: "500px", margin: '0px' }
page.paperSize = {
    
    
  width: '8.5in',
  height: '11in',
 margin: {
    
    
    top: '5px',
    left: '20px'
  },
  header: {
    
    
    height: "1cm",
    contents: phantom.callback(function(pageNum, numPages) {
    
    
      return "<h5>  <span style='color: #93a1a1;float:right'>deepblueAI-" + pageNum + " / " + numPages + "</span></h5>";
    })
  },
  footer: {
    
    
    height: "1cm",
    contents: phantom.callback(function(pageNum, numPages) {
    
    
      return "<h5>  <span style='color: #93a1a1;float:right'>deepblueAI-" + pageNum + " / " + numPages + "</span></h5>";
    })
  }
}

page.onLoadFinished = function () {
    
    
    console.log("html dom onLoadFinished");
}

var usage = function () {
    
    
    console.log("\nUsage: phantomjs echarts-convert.js -url xxx.html -outfile filename -options options" +
        "\n-outfile save file path" +
        "\n-options json str \n");
};

var getParams = function () {
    
    
    console.log("getParams for cmd \n");
    var map = {
    
    }, i, key;
    if (system.args.length < 2) {
    
    
        usage();
        phantom.exit();
    }
    for (i = 0; i < system.args.length; i += 1) {
    
    
        if (system.args[i].charAt(0) === '-') {
    
    
            key = system.args[i].substr(1, i.length);
            var vals = system.args[i + 1];
            console.log(key + " =  " + vals);
            if (key === 'url') {
    
    
                try {
    
    
                    map[key] = vals;
                } catch (e) {
    
    
                    console.log('Error: cannot find url, ' + system.args[i + 1]);
                    phantom.exit();
                }
            }else if (key === 'outfile') {
    
    
                try {
    
    
                    map[key] = vals;
                } catch (e) {
    
    
                    console.log('Error: cannot find outfile, ' + system.args[i + 1]);
                    phantom.exit();
                }
            } else {
    
    
                map[key] = vals;
            }

        }
    }

    console.log("options obj =  " + map[key]);

    return map;
};


function createChart(params) {
    
    
    var  options =  eval('(' + params + ')');
    deepblue.init(options);
    return {
    
    height: jQuery(document).height(),width : jQuery(document).width(),container : jQuery("#container").width()};
};



//getParams
var paramMap =getParams();

page.open(paramMap.url , function(status) {
    
    

    page.injectJs(config.JQUERY);
    page.injectJs(config.ECHARTS);
    page.injectJs(config.DEEPBLUE);


    console.log("http status:"+status);


    // get the dom height
    var viewRect= page.evaluate(createChart, paramMap.options);
    console.log('width ='+viewRect.width+ ' height='+viewRect.height + ' container='+viewRect.container   );
    // page.paperSize.height= height+"px";

    if( status == 'success' ) {
    
    

        setTimeout(function(){
    
    
            page.clipRect = {
    
    
                top : 0,
                left : 0,
                width : 840,
                height : viewRect.height
            };
            // page.render('test/example1.pdf');
            page.render(paramMap.outfile, {
    
    format: 'pdf', quality: '50'});
            console.log('success' );
            page.close();
            phantom.exit();
        }, 500);

    }else {
    
    
        console.log('render failed' );
        // exit
        phantom.exit();
    }
});

phantomjs /ads-monitor/html/echarts-convert.js -url file:ads-monitor/html/contractDashboard.html -outfile /ads-monitor/pdf/PDF-10-20210104165711.pdf -options {
    
    \"groupListData\":[{
    
    \"groupId\":22,\"groupName\":\"虹桥机场T1一楼屏幕\",\"materialUrlList\":[{
    
    \"materialName\":\"000\",\"materialTags\":\"5555\",\"materialType\":\"picture\",\"materialUrl\":\"http://degao-oss.oss-cn-shanghai.aliyuncs.com/materials/dev/16081164972335.jpg\",\"rid\":72}],\"palanResult\":{
    
    \"days\":16,\"nubPerDay\":1,\"totalNub\":24},\"pieData\":[{
    
    \"type\":\"normal\",\"value\":\"833.33\"},{
    
    \"type\":\"abnormal\",\"value\":\"-733.33\"}],\"planTimeIntervalList\":[{
    
    \"endTime\":1606705735000,\"purchaseCount\":10,\"rid\":24,\"startTime\":1605841734000},{
    
    \"endTime\":1608267599000,\"purchaseCount\":10,\"rid\":30,\"startTime\":1607961601000},{
    
    \"endTime\":1609394916000,\"purchaseCount\":4,\"rid\":37,\"startTime\":1609135712000}],\"progress\":\"12.50\",\"realResult\":{
    
    \"abnormalNub\":25,\"abnormalRate\":\"100.00\",\"days\":3,\"normalNub\":0,\"normalRate\":\"0.00\",\"nubPerDay\":0,\"totalNub\":3},\"taskTimeIntervalList\":[{
    
    \"endTime\":1608009134000,\"rid\":36,\"startTime\":1608098231000},{
    
    \"endTime\":1608220804000,\"rid\":42,\"startTime\":1608015979000},{
    
    \"endTime\":1607961600000,\"rid\":50,\"startTime\":1608134399000},{
    
    \"endTime\":1607961600000,\"rid\":52,\"startTime\":1608134399000},{
    
    \"endTime\":1607961600000,\"rid\":53,\"startTime\":1608134399000},{
    
    \"endTime\":1608134400000,\"rid\":54,\"startTime\":1608134399000},{
    
    \"endTime\":1607961600000,\"rid\":55,\"startTime\":1608134399000},{
    
    \"endTime\":1607961600000,\"rid\":56,\"startTime\":1608134399000},{
    
    \"endTime\":1608267599000,\"rid\":60,\"startTime\":1607961601000},{
    
    \"endTime\":1609394916000,\"rid\":66,\"startTime\":1609135712000}]},{
    
    \"groupId\":21,\"groupName\":\"浦东机场T1一楼屏幕\",\"materialUrlList\":[{
    
    \"materialName\":\"iphone12-白色\",\"materialTags\":\"白色|iphone\",\"materialType\":\"picture\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/2b13b64ded702c2c.jpg?Expires=1921200484&OSSAccessKeyId=LTAI4GDBhXMfswkafRVMiybj&Signature=dB3GKh9XQ3nVp515NoKOyP1fkVc%3D\",\"rid\":34},{
    
    \"materialName\":\"iphone12-黑色\",\"materialTags\":\"黑色|iphone12\",\"materialType\":\"picture\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/681fe3b14009da2f.jpg?Expires=1921200515&OSSAccessKeyId=LTAI4GDBhXMfswkafRVMiybj&Signature=gCgDFY%2B40K7NZW00gf7tDmOgr%2FU%3D\",\"rid\":35},{
    
    \"materialName\":\"testbyhanhao\",\"materialTags\":\"test\",\"materialType\":\"picture\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/ct5%E7%94%B7%E5%AD%A9.jpg?Expires=1922168178&OSSAccessKeyId=LTAI4GDBhXMfswkafRVMiybj&Signature=x8rtpIeQqF7XcydyrFhgp0I2M6I%3D\",\"rid\":44},{
    
    \"materialName\":\"花屏广告测试1\",\"materialTags\":\"8888\",\"materialType\":\"video\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/materials/dev/160811557329912.mp4\",\"rid\":70},{
    
    \"materialName\":\"videoTest测试名称长度测试名称长度测试名称长度测试名称长度测试名称长度测试名称长度\",\"materialTags\":\"333\",\"materialType\":\"video\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/materials/dev/160914457154710.mp4\",\"rid\":103},{
    
    \"materialName\":\"videoTest测试名称长度测试名称长度测试名称长度测试名称长度测试名称长度测试名称长度测试名称长度测试名称长度测试名称长度测试名称长度测试名称长度测试名称长度\",\"materialTags\":\"444\",\"materialType\":\"video\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/materials/dev/160914461256915.mp4\",\"rid\":104},{
    
    \"materialName\":\"03\",\"materialTags\":\"test\",\"materialType\":\"video\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/materials/dev/160861441998817.mp4\",\"rid\":98},{
    
    \"materialName\":\"testbyhanhao888\",\"materialTags\":\"888\",\"materialType\":\"picture\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/materials/dev/ct5%E7%94%B7%E5%AD%A9.jpg?Expires=1923121164&OSSAccessKeyId=LTAI4GDBhXMfswkafRVMiybj&Signature=SWFYT0qF4imIEd7FiBDDPVClkt4%3D\",\"rid\":52},{
    
    \"materialName\":\"花屏广告测试1\",\"materialTags\":\"6666\",\"materialType\":\"video\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/materials/dev/160811543745915.mp4\",\"rid\":69},{
    
    \"materialName\":\"360-胡宁\",\"materialTags\":\"360\",\"materialType\":\"video\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/materials/dev/160852502804915.mp4\",\"rid\":94},{
    
    \"materialName\":\"Linux先行者-冯晓焰\",\"materialTags\":\"linux\",\"materialType\":\"video\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/materials/dev/160851738926817.mp4\",\"rid\":93},{
    
    \"materialName\":\"面霸-左耳朵耗子\",\"materialTags\":\"左耳朵耗子\",\"materialType\":\"video\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/materials/dev/16085169580984.mp4\",\"rid\":92},{
    
    \"materialName\":\"花屏广告测试1\",\"materialTags\":\"444444444444444444444444444444|88888888888888888888888888888888888\",\"materialType\":\"video\",\"materialUrl\":\"https://degao-oss.oss-cn-shanghai.aliyuncs.com/materials/dev/16091450261533.mp4\",\"rid\":105}],\"palanResult\":{
    
    \"days\":16,\"nubPerDay\":1,\"totalNub\":24},\"planTimeIntervalList\":[{
    
    \"endTime\":1606705735000,\"purchaseCount\":10,\"rid\":24,\"startTime\":1605841734000},{
    
    \"endTime\":1608267599000,\"purchaseCount\":10,\"rid\":30,\"startTime\":1607961601000},{
    
    \"endTime\":1609394916000,\"purchaseCount\":4,\"rid\":37,\"startTime\":1609135712000}],\"progress\":\"0\",\"realResult\":{
    
    \"abnormalNub\":0,\"abnormalRate\":\"0\",\"days\":0,\"normalNub\":0,\"normalRate\":\"0\",\"nubPerDay\":0,\"totalNub\":0},\"taskTimeIntervalList\":[{
    
    \"endTime\":1608009134000,\"rid\":36,\"startTime\":1608098231000},{
    
    \"endTime\":1608220804000,\"rid\":42,\"startTime\":1608015979000},{
    
    \"endTime\":1607961600000,\"rid\":50,\"startTime\":1608134399000},{
    
    \"endTime\":1607961600000,\"rid\":52,\"startTime\":1608134399000},{
    
    \"endTime\":1607961600000,\"rid\":53,\"startTime\":1608134399000},{
    
    \"endTime\":1608134400000,\"rid\":54,\"startTime\":1608134399000},{
    
    \"endTime\":1607961600000,\"rid\":55,\"startTime\":1608134399000},{
    
    \"endTime\":1607961600000,\"rid\":56,\"startTime\":1608134399000},{
    
    \"endTime\":1608267599000,\"rid\":60,\"startTime\":1607961601000},{
    
    \"endTime\":1609394916000,\"rid\":66,\"startTime\":1609135712000}]}],\"headData\":{
    
    \"brandZnName\":\"淘宝\",\"consumerZnName\":\"测试创建1\",\"contractNo\":\"100001\",\"hqAriportPosition\":{
    
    \"lcdNub\":0,\"ledNub\":3,\"positionTotal\":3},\"pdAriportPosition\":{
    
    \"lcdNub\":1,\"ledNub\":7,\"positionTotal\":8},\"positionTotal\":11,\"rid\":10},\"playData\":{
    
    \"barOptionList\":[{
    
    \"time\":\"20201221\",\"type\":\"normal\",\"value\":0},{
    
    \"time\":\"20201221\",\"type\":\"abnormal\",\"value\":11},{
    
    \"time\":\"20201225\",\"type\":\"normal\",\"value\":0},{
    
    \"time\":\"20201225\",\"type\":\"abnormal\",\"value\":2}],\"lineOptionList\":[{
    
    \"time\":\"20201221\",\"value\":10},{
    
    \"time\":\"20201225\",\"value\":10}]}}

导出PDF样图如下
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zjcjava/article/details/112345988