记一次导出pdf表单引发的问题

需求:点击按钮,将相关内容生成pdf下载下来
在这里插入图片描述
问题1:之前项目封装好的下载文件方法不携带token
我尝试新写了一个方法,携带token
问题
问题2:此时出现了跨域问题
我分别尝试在controller类上和方法上加@CrossOrigin(origins = “*”)都无济于事。
我在拦截器里打了断点,发现浏览器发的请求头根本获取不到。在这里插入图片描述
在这里插入图片描述
原因是跨域请求浏览器会先发起一个预检请求,此时我们应该拦截并允许跨域在这里插入图片描述
跨域问题解决
==========================0
生成pdf需要引入这俩依赖

// https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf
	implementation("org.thymeleaf:thymeleaf:3.1.3.RELEASE")
// https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf
	implementation("org.xhtmlrenderer:flying-saucer-pdf:9.13.1")

thymeleaf+Flying Saucer(将html转换为pdf)

package com.jiangee.environment.utils;

import com.lowagie.text.pdf.BaseFont;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.xhtmlrenderer.css.parser.property.PageSize;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.ByteArrayOutputStream;
import java.util.Locale;
import java.util.Map;

@Component
public class ThymeleafPdf {
    @Resource
    private  TemplateEngine templateEngine;


    public byte[] generatePdf(String templateName, Map<String, Object> data) {
        Context context = new Context();
        context.setVariables(data);

        String htmlContent = templateEngine.process(templateName, context);

        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            ITextRenderer renderer = new ITextRenderer();
            renderer.setDocumentFromString(htmlContent);
            // 获取resources/下的文件
            //加载本地字体,不然不显示中文
            String fontPath = this.getClass().getClassLoader().getResource("font/simsun.ttc").getPath();
            renderer.getFontResolver().addFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            renderer.layout();
            renderer.createPDF(outputStream);
            return outputStream.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("Error generating PDF", e);
        }
    }
}
 public void exportHandoverSheet(String batchId, HttpServletResponse response) {
        // 准备数据
        Map<String, Object> data = new HashMap<>();
        Map<String, Object> invoice = new HashMap<>();
        invoice.put("number", "INV-2023-001");
        invoice.put("date", LocalDate.now());
        invoice.put("from", "ABC Company\n123 Main St\nNew York, NY 10001");
        invoice.put("to", "XYZ Client\n456 Oak Ave\nBoston, MA 02108");
        data.put("invoice", invoice);
        // 生成PDF
        byte[] pdfBytes = thymeleafPdf.generatePdf("invoice", data);
        // 3. 设置响应头
        response.setContentType(MediaType.APPLICATION_PDF_VALUE);
        response.setHeader("Content-Disposition", "attachment; filename=invoice.pdf");
        response.setContentLength(pdfBytes.length);
        // 4. 写入响应流
        try (OutputStream out = response.getOutputStream()) {
            out.write(pdfBytes);
            out.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

注:templateName是html名字,在这里插入图片描述
此时运行报错:找不到TemplateEngine,
需要再加一个依赖

// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf
	implementation("org.springframework.boot:spring-boot-starter-thymeleaf:3.5.2")
<!DOCTYPE html>
<html  lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta charset="UTF-8"/>
    <title>Invoice</title>
    <style>
        @page {
            size: A4 landscape; /* 横向A4 */
            margin: 1cm;
        }
        body { font-family: SimSun, sans-serif; margin: 20px; }
        .header { text-align: center; margin-bottom: 30px; }
        .info { margin-bottom: 20px; }
        table { width: 100%; border-collapse: collapse; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .total { text-align: right; font-weight: bold; }
    </style>
</head>
<body>
<div class="header">
    <h2>地下水环境调查送检样品交接表单</h2>
    <hr/>
</div>

<div class="info">
    <p><strong>From:</strong> <span th:text="${invoice.from}"></span></p>
    <p><strong>To:</strong> <span th:text="${invoice.to}"></span></p>
</div>

<table>
    <thead>
    <tr>
        <th>Description</th>
        <th>Quantity</th>
        <th>Unit Price</th>
        <th>Amount</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="item : ${invoice.items}">
        <td th:text="${item.description}"></td>
        <td th:text="${item.quantity}"></td>
        <td th:text="${'$' + #numbers.formatDecimal(item.unitPrice, 1, 2)}"></td>
        <td th:text="${'$' + #numbers.formatDecimal(item.quantity * item.unitPrice, 1, 2)}"></td>
    </tr>
    </tbody>
</table>

<div class="total">
    <h3>Total: <span th:text="${'$' + #numbers.formatDecimal(invoice.total, 1, 2)}"></span></h3>
</div>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值