后端导出PDF文件(付前端实现代码)

JAVA后端导出PDF文件


前言

效果图:

一、前端代码

// 直接用href请求后端地址即可
window.location.href = http://localhost:8989/exportPdf;

二、使用步骤

1. ftl模板

注意:贴出的接口代码,读取的ftl模板的路径是,src\main\resources\templates\free.ftl

<#-- 如果值为null/空,则设置为空值 -->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Freemarker</title>
    <style type="text/css">
        #all {
            width: 600px;
        <#-- 使文档在pdf页面居中 --> margin: auto;
        }

        table {
            width: 100%;
            height: auto;
        <#-- @@提醒@@:此处必须指定字体,不然不识别中文  --> font-family: SimSun;
            text-align: center;
        <#-- table中单元格自动换行 --> table-layout: fixed;
            word-wrap: break-word;
        }

        tr td {
            padding: 2px;
            font-size: 10px;
            height: 20px;
        }

        tr th {
            padding: 2px;
            font-weight: bold;
            font-size: 10px;
            height: 20px;
        }
    </style>
</head>
<body>
<div id="all">
    <table border="1" cellspacing="0" cellpadding="0" align="center">
        <tr>
            <th colspan="5">${title}</th>
        </tr>
        <tr>
            <#-- 动态获取params的大小size -->
            <th rowspan="${params?size+1}">基本信息</th>
            <td>姓名</td>
            <td>电话</td>
            <td>昵称</td>
            <td>邮箱</td>
        </tr>
        <#list params as param>
            <tr>
                <td>${param.name}</td>
                <td>${param.phone}</td>
                <td>${param.nickname}</td>
                <td>${param.email}</td>
            </tr>
        </#list>
    </table>
</div>
</body>
</html>

2.后端代码

依赖:

 <dependency>
      <groupId>org.xhtmlrenderer</groupId>
      <artifactId>flying-saucer-pdf-itext5</artifactId>
      <version>9.0.3</version>
  </dependency>
  
  <dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.13.1</version>
  </dependency>
  
  <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.30</version>
  </dependency>
      
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  
 <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <version>${lombok.version}</version>
 </dependency>
 
   <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.6.0</version>
    </dependency>

2.1 核心接口代码

package com.example.export;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 导出pdf
 *
 */
@Slf4j
@RestController
public class ExportPdf {


    @GetMapping("/exportPdf")
    public void exportPdf(HttpServletResponse response) {
        // ========== pdf处理方式 ===========
        Map<String, Object> map1 = new HashMap<>();
        map1.put("name", "赵小刚");
        map1.put("phone", "15673890987");
        map1.put("nickname", "红孩儿");
        map1.put("email", "15673890987@163.com");

        Map<String, Object> map2 = new HashMap<>();
        map2.put("name", "赵小刚");
        map2.put("phone", "15673890987");
        map2.put("nickname", "红孩儿");
        map2.put("email", "15673890987@163.com");
        List<Map<String, Object>> stuffList = Arrays.asList(map1,map2);

        Map<String, Object> stuffMap = new HashMap<>();
        stuffMap.put("params", stuffList);
        stuffMap.put("title", "测试PDF模板");


        File pdfFile = FileUtil.file("test.pdf");
        try (OutputStream os = new FileOutputStream(pdfFile);) {
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
            // 如果填充值中与模板不匹配,或者为null值,则默认此值为空;
            cfg.setClassicCompatible(true);
            // 模板路径加载方式:基于类路径,即在src\main\resources\templates包下的ftl模板
            cfg.setClassForTemplateLoading(this.getClass(),"/templates");
            Template template = cfg.getTemplate( "pdf.ftl");
            Writer writer = new StringWriter();
            template.process(stuffMap, writer);

            // 对pdf资料进行创建
            HtmlToPdf.htmlToPdf(writer.toString(),os);
            byte[] dataByte = FileUtil.readBytes(pdfFile);

            response.addHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(dataByte.length));
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=%s"
                    , URLEncoder.encode("pdf测试.pdf", "UTF-8")));
            IoUtil.write(response.getOutputStream(), Boolean.TRUE, dataByte);

        } catch (Exception e) {
            log.error("导出贷后检查表失败, 详情:{}", e.getMessage());
        } finally {
            // 删除项目classes/目录下生成的临时文件
            if (pdfFile.exists()) {
                FileUtil.del(pdfFile);
            }
        }


    }

}

2.2 本地方法 HtmlToPdf.htmlToPdf()

package com.example.export;

import cn.hutool.core.util.StrUtil;
import com.itextpdf.text.pdf.BaseFont;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.OutputStream;

 /**
     * 将HTML转成PD格式的文件。html文件的格式比较严格
     * @param htmlText  html内容
     * @param os   pdf存储文件输出流, 需要调用方关闭流
     * @throws Exception
     */
    public static void htmlToPdf(String htmlText, OutputStream os) throws Exception {
        // <!DOCTYPE html> 没有闭合标签,故删掉
        htmlText = htmlText.replace("<!DOCTYPE html>", StrUtil.EMPTY);
        Document document = Jsoup.parse(htmlText);
        /*手动为一些标签添加闭合*/
        Elements meta = document.getElementsByTag("meta");
        String html = document.html();
        for (Element link : meta) {
            String s = link.outerHtml();
            String s1 = s.replace("/>", ">");
            html = html.replace(s, s1 + "</meta>");
        }
        Elements link1 = document.getElementsByTag("link");
        for (Element link : link1) {
            String s = link.outerHtml();
            String s1 = s.replace("/>", ">");
            html = html.replace(s, s1 + "</link>");

        }
        html = html.replaceAll("<br>", "<br/>");
        html = html.replaceAll("&nbsp", "&#160");

        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocumentFromString(html);
        // 解决中文支持, 注意本地和生产必须有此字体文件
        ITextFontResolver fontResolver = renderer.getFontResolver();
        String currentSystem = System.getProperty("os.name").toLowerCase();
        if("linux".equals(currentSystem)){
            fontResolver.addFont("/usr/share/fonts/chinese/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);
    }

3.测试

启动项目,使用浏览器请求:http://localhost:8989/exportPdf
即可实现导出pdf测试文件

(本文完!转载需说明出处!)

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
实现前端layui后端Java实现PDF导出,可以使用以下步骤: 1. 前端使用layui中的表格组件展示需要导出的数据。 2. 前端通过Ajax请求将数据发送到后端后端使用Java处理数据。 3. 后端使用Java PDF库(如iText)生成PDF文件。 4. 后端将生成的PDF文件发送到前端前端通过浏览器下载即可。 以下是大致的代码实现前端代码: ```html <table id="tableData" lay-filter="tableData"></table> <button id="exportBtn" class="layui-btn layui-btn-normal">导出PDF</button> <script> // 初始化表格 layui.use('table', function(){ var table = layui.table; table.render({ elem: '#tableData', url: 'data.json', // 数据接口 cols: [[ {field: 'id', title: 'ID'}, {field: 'name', title: '名称'}, {field: 'price', title: '价格'} ]] }); // 导出按钮点击事件 $('#exportBtn').click(function() { // 获取表格数据 var data = table.cache.tableData; // 发送数据到后端 $.ajax({ type: 'POST', url: '/export/pdf', data: JSON.stringify(data), contentType: 'application/json', success: function(res) { // 下载PDF文件 window.location.href = res.url; } }); }); }); </script> ``` 后端代码: ```java @PostMapping("/export/pdf") public ResponseEntity<Resource> exportPdf(@RequestBody List<Map<String, Object>> data) throws Exception { // 生成PDF文件 ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfDocument pdf = new PdfDocument(new PdfWriter(baos)); Document document = new Document(pdf); Table table = new Table(3); table.addCell(new Cell().add(new Paragraph("ID"))); table.addCell(new Cell().add(new Paragraph("名称"))); table.addCell(new Cell().add(new Paragraph("价格"))); for (Map<String, Object> row : data) { table.addCell(new Cell().add(new Paragraph(row.get("id").toString()))); table.addCell(new Cell().add(new Paragraph(row.get("name").toString()))); table.addCell(new Cell().add(new Paragraph(row.get("price").toString()))); } document.add(table); document.close(); // 构建响应体 ByteArrayResource resource = new ByteArrayResource(baos.toByteArray()); HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=data.pdf"); headers.add(HttpHeaders.CONTENT_TYPE, "application/pdf"); return ResponseEntity.ok() .headers(headers) .contentLength(resource.contentLength()) .body(resource); } ``` 注意事项: 1. 要使用iText库,需要在项目中添加对应的依赖,可以在Maven中添加以下依赖: ```xml <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-core</artifactId> <version>7.1.15</version> </dependency> ``` 2. 前端需要使用jQuery库和layui框架,需要在HTML文件中添加对应的依赖。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_函数_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值