java实现写字板对pdf文件签名

发布时间:2023-04-03 13:30

java实现写字板对pdf文件签名

思路

首先明白写字板签名完输出的是base64的图片,剩下的就是将此图片插入到pdf文件中,实现此步骤的技术很多,可以用itex5但是为了实现与其他数据一起动态插入我选择的freemark。

大概就是:签字版签名图片———》将图片插入ftl模板生成html文件—————》将html文件转成pdf(使用技术是wkhtmltopdf)

技术介绍

freemark:http://freemarker.foofun.cn/

FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

wkhtmltopdf:https://wkhtmltopdf.org/

khtmltoimage是开源 (LGPLv3) 命令行工具,可使用 Qt WebKit 渲染引擎将 HTML 渲染为 PDF 和各种图像格式。这些完全“无头”运行,不需要显示或显示服务。

前面有此驱动的具体用法

上代码

具体实现

依赖

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-freemarkerartifactId>
    <version>2.1.10.RELEASEversion>
dependency>

1.对html模板改造

使用${}进行动态数据插入

2.编写控制层

freemarker默认是map集合传参方式键值对

键为${}中的pic,值为你需要插入的图片地址可以为虚拟路径

入参的数据源如果需要插入的字段不一样

3.ftl插入数据生成html工具类

/**
 * freemarker配置 可以读取我们在yml中的配置,比如模版文件的路径,
 */
@Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;

@Value("${file.root.path}")
private String rootPath;

/**
 * 通过JSON生成Html,Excel,Word
 *
 * @param data             数据源
 * @param fileName         文件名
 * @param templateFilePath 模板文件路径
 * @param templateFile     模板
 */
public static void createDayReportFiles(Map<String, Object> data, String fileName, String templateFilePath, String templateFile) {
    BufferedInputStream in = null;
    Writer out = null;
    Template template = null;
    try {

        //构造Configuration
        Configuration configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        configuration.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
        configuration.setDirectoryForTemplateLoading(new File(templateFilePath));


        try {
            //test.ftl为要装载的模板
            template = configuration.getTemplate(templateFile);
        } catch (IOException e) {
            e.printStackTrace();
        }


        //输出文档路径及名称
        File outFile = new File(fileName);

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(outFile);
            OutputStreamWriter oWriter = new OutputStreamWriter(fos, "UTF-8");
            //这个地方对流的编码不可或缺,使用main()单独调用时,应该可以,但是如果是web请求导出时导出后word文档就会打不开,并且包XML文件错误。主要是编码格式不正确,无法解析。
            out = new BufferedWriter(oWriter);

        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }


        //生成HTML
        template.process(data, out);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (TemplateException e) {
        e.printStackTrace();
    } finally {
        if (null != in) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != out) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

4.html文件转pdf工具类

有了带数据的html文件剩下的就是将此html文件转成pdf就行了

/**
 * html转pdf
 * @param srcPath html路径,可以是硬盘上的路径,也可以是网络路径
 * @param destPath pdf保存路径
 * @return 转换成功返回true
 */
public static boolean convert(String srcPath, String destPath){
    File file = new File(destPath);
    File parent = file.getParentFile();
    //如果pdf保存路径不存在,则创建路径
    if(!parent.exists()){
        parent.mkdirs();
    }
    
    StringBuilder cmd = new StringBuilder();
    cmd.append(toPdfTool);
    cmd.append(" ");
    cmd.append("  --header-line");//页眉下面的线
    cmd.append("  --header-center 这里是页眉这里是页眉这里是页眉这里是页眉 ");//页眉中间内容
    //cmd.append("  --margin-top 30mm ");//设置页面上边距 (default 10mm) 
    cmd.append(" --header-spacing 10 ");//    (设置页眉和内容的距离,默认0)
    cmd.append(srcPath);
    cmd.append(" ");
    cmd.append(destPath);
    
    boolean result = true;
    try{
        //执行拼接后的命令
        Process proc = Runtime.getRuntime().exec(cmd.toString());
        HtmlToPdfInterceptor error = new HtmlToPdfInterceptor(proc.getErrorStream());
        HtmlToPdfInterceptor output = new HtmlToPdfInterceptor(proc.getInputStream());
        error.start();
        output.start();
        proc.waitFor();
    }catch(Exception e){
        result = false;
        e.printStackTrace();
    }

    return result;
}

到此完美结束,核心代码就这么多,剩下的就是与你业务逻辑匹配就行,比如文件命名,保存位置,插入的数据。

有更好的方案欢迎与我一起讨论多多指教

5.效果图
完蛋图片传不上来

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号