当前位置: 首页 > article >正文

Freemarker和ItextPDF实际应用

1. FreeMarker模板文件路径

确保FreeMarker模板文件位于正确的路径,并通过Spring Boot自动加载。模板文件放在 src/main/resources/templates/ 目录下,FreeMarker会自动处理这些文件。

@Configuration
public class FreeMarkerConfig {

    @Value("${spring.freemarker.prefix:classpath:/templates/}")
    private String freemarkerTemplatePrefix;

    @Bean
    public Configuration freemarkerConfiguration() {
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_31);
        try {
            configuration.setDirectoryForTemplateLoading(new File(freemarkerTemplatePrefix));
        } catch (IOException e) {
            e.printStackTrace();
        }
        configuration.setDefaultEncoding("UTF-8");
        return configuration;
    }
}

2. 模板文件(template.ftl)

模板文件内容,放在 src/main/resources/templates/ 目录下:

<!DOCTYPE html>
<html>
<head>
    <title>${title}</title>
</head>
<body>
    <h1>${title}</h1>
    <p>${content}</p>
</body>
</html>

3. 图片路径(seal.png)

将章图片 seal.png 放在 src/main/resources/static/images/ 目录下。Spring Boot会自动处理这些资源,你可以通过类加载器获取并加载它。

4. PDF生成逻辑(PDFGenerator.java)

改进后的 PDFGenerator.java,支持动态加载模板和图片,生成带章的PDF文件,并灵活调整章的位置。

package com.example.demo;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.Image;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

@Service
public class PDFGenerator {

    public void generatePdfWithSeal(String outputPdfPath, String sealImagePath) {
        try {
            // 模板数据
            Map<String, Object> dataModel = new HashMap<>();
            dataModel.put("title", "带章的PDF文件");
            dataModel.put("content", "这是一份动态生成的带章PDF文件。");

            // FreeMarker模板文件路径
            String templateFile = "template.ftl";

            // 创建FreeMarker配置
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
            cfg.setClassForTemplateLoading(PDFGenerator.class, "/templates");  // 设置模板目录
            Template template = cfg.getTemplate(templateFile);

            // 使用FreeMarker处理模板
            StringWriter stringWriter = new StringWriter();
            template.process(dataModel, stringWriter);
            String generatedText = stringWriter.toString();

            // 创建PDF文件
            createPdfWithSeal(outputPdfPath, generatedText, sealImagePath);  // 图片路径

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void createPdfWithSeal(String outputPdfPath, String text, String sealImagePath) throws Exception {
        // 创建一个空的PDF文件
        OutputStream outputStream = new FileOutputStream(outputPdfPath);
        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, outputStream);

        document.open();

        // 添加内容
        document.add(new Paragraph(text));

        // 通过类加载器加载章图片(解决WAR包内路径问题)
        InputStream sealInputStream = getClass().getClassLoader().getResourceAsStream(sealImagePath);
        if (sealInputStream != null) {
            Image sealImage = Image.getInstance(sealInputStream);
            // 获取PDF页面的大小,并动态调整章位置
            Rectangle pageSize = writer.getPageSize();
            float x = pageSize.getWidth() - 150;  // 章离右边缘150px
            float y = pageSize.getHeight() - 150;  // 章离下边缘150px
            sealImage.setAbsolutePosition(x, y); 
            sealImage.scaleToFit(100, 100);  // 调整章的大小
            document.add(sealImage);
        } else {
            System.err.println("章文件未找到:" + sealImagePath);
        }

        document.close();
        outputStream.close();
    }
}

5. Spring Boot Controller(PDFController.java)

为了便于测试并下载生成的PDF文件,创建一个REST接口,返回PDF文件流。

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

@RestController
public class PDFController {

    @Autowired
    private PDFGenerator pdfGenerator;

    @GetMapping("/generate-pdf")
    public ResponseEntity<byte[]> generatePdf() throws IOException {
        String outputPdfPath = "output.pdf";
        String sealImagePath = "images/seal.png";  // 章图片路径

        // 调用PDF生成方法
        pdfGenerator.generatePdfWithSeal(outputPdfPath, sealImagePath);

        File generatedFile = new File(outputPdfPath);
        if (generatedFile.exists()) {
            byte[] fileContent = Files.readAllBytes(generatedFile.toPath());
            // 返回PDF文件作为下载
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"output.pdf\"")
                    .contentType(MediaType.APPLICATION_PDF)
                    .body(fileContent);
        } else {
            return ResponseEntity.status(500).body(null);
        }
    }
}

6. Spring Boot配置(application.properties)

确保配置了FreeMarker模板的正确路径,配置如下:

spring.freemarker.prefix=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.charset=UTF-8

7. 静态资源存放路径

seal.png放在src/main/resources/static/images/目录下,这样Spring Boot会自动处理和提供访问。

8. 目录结构

确保项目目录结构如下:

src/
  main/
    java/
      com/
        example/
          demo/
            PDFGenerator.java         // PDF生成逻辑
            PDFController.java        // REST控制器
            DemoApplication.java      // Spring Boot启动类
    resources/
      static/
        images/
          seal.png                  // 章图片
      templates/
        template.ftl                // FreeMarker模板
      application.properties        // Spring Boot配置文件

9. 运行项目

  1. 启动项目:运行Spring Boot应用程序,可以使用命令:

    mvn spring-boot:run
    
  2. 访问接口:打开浏览器或使用Postman访问:

    http://localhost:8080/generate-pdf
    

    这会触发PDF生成并返回下载链接。

10. 测试与调试

  1. 如果PDF文件生成成功,它会自动作为附件下载。
  2. 如果出现问题,检查控制台日志,确保:
    • 图片路径正确。
    • 模板路径正确。
    • PDF文件生成没有错误。


http://www.kler.cn/a/513312.html

相关文章:

  • js截取video视频某一帧为图片
  • Unity预制体未即时刷新
  • 基础jjj
  • 数据结构学习记录-队列
  • kafka学习笔记4-TLS加密 —— 筑梦之路
  • 函数递归的介绍
  • GBase8c aes_encrypt和aes_decrypt函数
  • mysql的测试方案
  • P8738 [蓝桥杯 2020 国 C] 天干地支
  • Oracle 深入学习 Part 14:Managing Password Security and Resources(管理密码安全性和资源)
  • python中Mako用法
  • 深入探索Math.NET:开启高效数值计算之旅
  • C++通过输入3D相机像素点集{u、v、z}和机械手世界坐标点集{X、Y、Z}求得变换矩阵RT(眼在手外)
  • 将 Docker 安装到 Windows 的 D 盘的方法
  • 麦田物语学习笔记:保存和加载场景中的物品
  • StyleGAN - 基于样式的生成对抗网络
  • 低度酒真的是酒精勾兑的吗?
  • 2024人工智能AI+制造业应用落地研究报告汇总PDF洞察(附原数据表)
  • 【Java数据结构】排序
  • 前端之移动端
  • 解锁Java中的国密算法:安全保障的密钥
  • Arweave的经济学模型
  • TiDB与Oracle:数据库之争,谁能更胜一筹?
  • HTML语言的数据结构
  • git常见知识点
  • 使用tritonserver完成clip-vit-large-patch14图像特征提取模型的工程化。