Spring boot实现自定义html页面转pdf,并下载

场景:

将前端传入的值,直接插入指定的模板中,来生成pdf租房合同,生成的pdf样式,使用html页面来控制。

代码如下:

首先:

使用了velocity模板引擎技术来实现传值稳定插入到指定位置。

以上是html模板 ,要求html遵守xhtml的规范,严格语法要求。

然后下面是引用的maven坐标

 <dependencies>

        <!-- velocity依赖 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity.tools</groupId>
            <artifactId>velocity-tools-generic</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity.tools</groupId>
            <artifactId>velocity-tools-view</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity.tools</groupId>
            <artifactId>velocity-tools-view-jsp</artifactId>
            <version>3.0</version>
        </dependency>

        <!-- freemarker 读取html模板文件 -->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.23</version>
        </dependency>
        <!-- xml 将html模板文件转换成pdf -->
        <dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>flying-saucer-pdf</artifactId>
            <version>9.1.8</version>
        </dependency>

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.11</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf.tool</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.5.8</version>
        </dependency>
        <dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>flying-saucer-pdf</artifactId>
            <version>9.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-pdfa</artifactId>
            <version>5.5.8</version>
        </dependency>

        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.19</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>


    </dependencies>

然后上代码:

扫描二维码关注公众号,回复: 15075953 查看本文章

接口层:


import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.RandomUtil;
import com.xr.common.constant.Constants;
import com.xr.common.core.domain.R;
import com.xr.rent.underlease.underleaseroom.domain.RentUnderLeaseRoom;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Properties;

@Api(tags = "获取租赁模板")
@RestController
@RequestMapping("/redPdfModelController")
public class RedPdfModelController {


    @ApiOperation(value = "获取传入数据后的内容", httpMethod = "GET")
    @PostMapping("/getModel")
    //这里传值
    public R get(@RequestBody RentUnderLeaseRoom rentUnderLeaseRoom, HttpServletResponse response) throws FileNotFoundException {
        VelocityEngine ve = new VelocityEngine();
        Properties p = new Properties();

        // 加载classpath目录下的vm文件,指定vm文件加载目录
        p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8);
        // 初始化Velocity引擎,指定配置Properties
//        Velocity.init(p);
        ve.setProperty(Velocity.ENCODING_DEFAULT, "UTF-8");
        ve.setProperty(Velocity.INPUT_ENCODING, "UTF-8");    //指定编码格式,避免生成模板就造成乱码
        ve.init(p);

        //取得velocity的模板
        Template t = ve.getTemplate("vmmodel/contract.html.vm", "UTF-8");

        //取得velocity的上下文
        VelocityContext context = new VelocityContext();
        //往vm中写入信息
        //写入自己要插入的信息,
        context.put("username", rentUnderLeaseRoom.getUnitName());
        StringWriter writer = new StringWriter();

        //把数据填入上下文
        t.merge(context, writer);

        //输出流
        String testPath = "";

        String pdfDownlad = "";


        String out = writer.toString();
        String osName = System.getProperty("os.name");
        if (osName.toLowerCase().startsWith("win")) {
            testPath = "D:\\checkHtml\\" + RandomUtil.randomNumbers(20) + ".html";
            pdfDownlad = "D:\\testPdf\\" + RandomUtil.randomNumbers(20) + ".pdf";
        } else {
            testPath = "/opt/checkHtml/" + RandomUtil.randomNumbers(20) + ".html";
            pdfDownlad = "/opt/checkPdf/" + RandomUtil.randomNumbers(20) + ".pdf";
        }


        File file = new File(testPath);

        FileWriter fileWriter = FileWriter.create(file);
        fileWriter.write(out);


        try {
            FileTypeConvertUtil.html2pdf(file.getAbsolutePath(), pdfDownlad);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


        BufferedInputStream bis = null;
        OutputStream os = null;
        FileInputStream fileInputStream = null;

        try {
            fileInputStream = new FileInputStream(pdfDownlad);
            byte[] buff = new byte[1024];
            bis = new BufferedInputStream(fileInputStream);
            os = response.getOutputStream();

            int i = bis.read(buff);
            while (i != -1) {
                os.write(buff, 0, buff.length);
                i = bis.read(buff);
                os.flush();
            }
            os.flush();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    return R.fail("导出失败");
                }
            }
        }

        response.setCharacterEncoding("utf-8");
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename=Encrypt.pdf");


        return R.ok("下载成功");
    }




}

用到的工具类: 通过这个工具类来讲html转换为pdf,可先用main方法进行测试。

package com.xr.rent.readpdfmodel.controller;

import com.itextpdf.text.pdf.BaseFont;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;

/**
 * 文件格式转换工具类
 *
 * @author lbj
 * <p>
 * 2015-10-8 上午10:52:22
 */
public class FileTypeConvertUtil {

    /**
     * 将HTML转成PD格式的文件。html文件的格式比较严格
     *
     * @param htmlFile
     * @param pdfFile
     * @throws Exception
     */
    // <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
    public static void html2pdf(String htmlFile, String pdfFile) throws Exception {
        // step 1
        String url = new File(htmlFile).toURI().toURL().toString();
        System.out.println(url);
        // step 2
        OutputStream os = new FileOutputStream(pdfFile);
        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocument(url);

        // step 3 解决中文支持
        ITextFontResolver fontResolver = renderer.getFontResolver();
        if ("linux".equals(getCurrentOperatingSystem())) {
            fontResolver.addFont("/usr/share/fonts/chiness/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        } else {
            fontResolver.addFont("c:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        }

        renderer.layout();
        renderer.createPDF(os);
        os.close();

        System.out.println("create pdf done!!");

    }

    public static String getCurrentOperatingSystem() {
        String os = System.getProperty("os.name").toLowerCase();
        System.out.println("---------当前操作系统是-----------" + os);
        return os;
    }


    public static void main(String[] args) {
        //        String htmlFile = "/home/lbj/sign.jsp";
        //        String pdfFile = "/home/lbj/sign.pdf";
        String htmlFile = "d:/table.html";
        String pdfFile = "d:/testoone2.pdf";
        try {
            FileTypeConvertUtil.html2pdf(htmlFile, pdfFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

vm模板: 使用此模板来进行渲染

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8"/>
    <title>表格样式</title>
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"/>
    <link rel="stylesheet" href="https://static.loyalvalleycapital.com/web/css/frame.css"/>
    <style>

    </style>
</head>
<body class="bg-white pb-3" style="font-family: SimSun;">
<h1>合同</h1>
<h2>甲方:${username}</h2>
</body>
</html>

以上就是全部代码,下面是效果图。

可以自定义css和html表现来实现效果。

猜你喜欢

转载自blog.csdn.net/seeblood/article/details/130258570
今日推荐