rayin使用与学习

简介: rayin使用与学习

一、背景

      基于html生成pdf的使用场景比较多,我在的上家公司做电子合同需求的时候,是我这边完成的,当时是基于itext生成PDF的。电子合同作为一个电签中必不可少的一部分,如何高效实现html生成pdf,是我们必须要解决的问题。如果使用电子合同,此时必然需要对接相关的电子合同厂家,比如E签宝、法大大、上上签、电子牵等。当时生成的pdf没有作者想的这么周到,不过这次做需求,再次看到这个项目,还是很开心很乐意和大家分享这个项目的,也感谢rayin的作者开源了这么好的项目。

项目地址:https://gitee.com/Rayin/rayin

二、使用场景

各种电子合同、病历模板、动态模板、各种结算单、各种账单、发票等等,使用场景非常广泛。

当然本次我这边需要完成一个财务那边的结算单电子存档,此时由于涉及图片、表单、二维码、相关结算金额问题。起初我打算使用基于itext直接生成。我之前做过电子合同的需求,知道itext对于样式的兼容不是很好。因此本次,我这边使用rayin来进行pdf生成,主要开源的这个项目很好的满足了我的需求。

之所以推荐rayin来生成pdf,在于rayin的便利性。有快速上手的example,对样式进行了兼容,不会出现截断,同时快速生成的效率。

三、基于html+json数据生成效果


四、基于html+json数据+excel生成效果


从上面生成的效果可以出生成的效果,样式得到了很好的渲染,同时支持图片的插入。看起来很精美。

五、如何实现上面效果

我们看到了效果,那它是怎么实现上面的效果的呢?

1)快速开始

可以看到excel里面基于excel+json数据+html生成、基于html+json数据、基于模板+规则groovy生成,除此之外,还有性能测试。


可以看到作者很贴心的准备了很多的example,让我们可以快速开始,了解使用rayin生成不同的pdf。

根据example5来看:

public void exp05ComplexElementBindDataGenerateTest() throws Exception {
        //获取数据路径信息
        String jsonDataFilePath = ResourceUtil.getResourceAbsolutePathByClassPath("examples/example5/data.json");
        // 将json数据进行解析
        JsonNode jsonDataNode = JsonSchemaValidator.getJsonNodeFromFile(jsonDataFilePath);
        //依据单个构建配置生成PDF
        JSONObject jsonData = JSONObject.parseObject(jsonDataNode.toString());
        String outputFileClass = ResourceUtil.getResourceAbsolutePathByClassPath("");
        // 生成pdf路径
        String outputFile = new File(outputFileClass)
                .getParentFile().getParent()
                + "/tmp/"
                + "example05_openhtmltopdf_"+System.currentTimeMillis() + ".pdf";
        StopWatch watch = StopWatch.createStarted();
        // 生成PDF: html的路径、json数据、输出pdf文件的路径
  pdfGenerator.generatePdfFileByHtmlAndData(ResourceUtil.getResourceAbsolutePathByClassPath("examples/example5/element1.html"),jsonData,outputFile);
        watch.stop();
    }

2)调用生成pdf文件的核心方法

pdfGenerator.generatePdfFileByHtmlAndData(ResourceUtil.getResourceAbsolutePathByClassPath("examples/example5/element1.html"),jsonData,outputFile); 这个方法中,可以看到需要html的路径,json数据,输出文件路径。

也即基于html和jsonData,来构建pdf,从而生成PDF。从resource中,我们可以看到里面包含html和json数据,当然这里的json数据是为了测试方便,在真实的业务场景下,json数据来源于业务中。


此时我们关心的是json数据如何填充到html中,然后渲染相关样式,然后生成PDF。

3)填充html构件字符串过程

public String templateEngineProcessByString(String htmlStr, JSONObject jsonData){
        // 创建上下文对象,如果json数据不为空,则设置变量
         Context context  = new Context();
        if(jsonData != null){
            context.setVariables(JSON.parseObject(jsonData.toJSONString(), Map.class));
        }
        String r = null;
        try{
            // 通过模板引擎处理,拿到json的字符串
            r = templateEngine.process(htmlStr, context);
        }catch(Exception e){
            r = e.getCause().toString().replace("org.attoparser.ParseException: Exception evaluating OGNL expression:","The Data paraeter error:");
        }
        return r;
    }

而这个过程是通过模板引擎thyemleaf进行处理得到的。核心方法:templateEngine.process(htmlStr, context),调用模板引擎处理从而完成数据的填充工作。

4)样式渲染处理

完成数据填充之后,还需要考虑样式的问题。因此在这个方法中,进行数据样式相关信息的处理:generatePdfStreamByHtmlStr(String htmlContent, Set markKeys),下面是对相关标签的渲染处理:


可以看到最终生成PDF的渲染工作借助了openhtmltopdf这个开源项目。不得不说这个框架也是够强大的。

到这里,html完成了向PDF的过渡,最终FileUtils.writeByteArrayToFile(new File(outputFile), generatePdfStreamByHtmlStr(htmlStr).toByteArray())生成PDF。

当然这里涉及到这个字体的问题:

5) 字体的设置

public static void init() {
        synchronized(OpenhttptopdfRendererObjectFactory.class) {
            // 进行字体缓存
            factory.FontCache();
            //设置对象池的相关参数
            GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
            //最大空闲数
            poolConfig.setMaxIdle(MaxIdle);
            //最大线程数
            poolConfig.setMaxTotal(MaxTotal);
            //最小线程数
            poolConfig.setMinIdle(MinIdle);
            poolConfig.setSoftMinEvictableIdleTimeMillis(SoftMinEvictableIdleTimeMillis);
            //新建一个对象池,传入对象工厂和配置
            objectPool = new GenericObjectPool<OpenhttptopdfRenderBuilder>(factory, poolConfig);
        }
    }

可以看到对象池中存放了对象池的池配置信息和字体信息。方便后续的渲染使用,因为后续使用渲染成PDF的正是使用了这个构建器。

如果想自定义字体可以调用:

void init(String customizeFontPathDirectory);

除此之外,还可以自定义设置对象池的配置:

void init(int minIdle,int maxIdle,int maxTotal, String customizeFontPathDirectory);

6) rayin提供生成PDF的相关方式

从PdfGenerator接口,生成PDF的方式包含两种:

基于html+json数据生成PDF
基于html+json数据+excel生成PDF

还有基于groovy规则生成PDF。

当然除此之外,还有很多开源项目是基于html生成pdf的,比如经典的itext,openpdf、openhtmltopdf、jasper、x-easypdf等。

参考:https://gitee.com/Rayin/rayin

目录
相关文章
|
3月前
学习putpixel画点
学习putpixel画点。
62 20
|
3月前
学习使用按位取反~
学习使用按位取反~。
27 6
|
4月前
|
Linux
ACPI学习
ACPI学习
|
NoSQL Java jenkins
|
NoSQL Java jenkins
【学习总结】总结
【学习总结】总结
|
设计模式 安全 Java
【鸟瞰】C#的学习
前言: 在软件工程之C/S学习的过程中,我们已经学习过了软件工程,文档,九种UML图。下一个学习小阶段是C#和设计模式,视频里的老师上来就讲“.NET”,还说应该念成“dot Net”,念成“点NET”实在是太不专业了。我突然有点蒙圈了,为啥在这个阶段要学习C#?学C#为啥还和“dot Net”有关?怎么这么多C?什么C语言?C ++?C#?这些都是些什么鬼?晕!!! 于是开始在培养计划中寻找答案。。。
105 0
|
弹性计算 Java 关系型数据库
学习介绍
解压tomcat压缩包 tar -zxvf apache-tomcat-8.5.70.tar.gz。 解 在idea将下面打包成war,通过命令传到服务器的tomcat里面,传进去后将会自己解压 通过这次的云服务器ECS的使用,我收获颇丰,第一次将项目放到了服务器上进行访问,在过程中,因为我目前使用的springboot,所以在tomcat上面使用较少,遇到大多数问题是部署到云服务器上端口以及连接的错误和Linux指令的不熟悉,我经常通过网络找各种解决办法,配置端口,删除重新解压一下,最后才能使用,将这次的心得体会写下来,以后再次使用阿里云服务器的时候,我看看通过这个文章,可以更快的部署服务器
|
前端开发 NoSQL 算法
需要学习
需要学习
214 0
|
Web App开发 存储 XML
|
C# Windows 程序员