Freemarker和ItextPDF现实应用

打印 上一主题 下一主题

主题 873|帖子 873|积分 2619

1. FreeMarker模板文件路径

确保FreeMarker模板文件位于正确的路径,并通过Spring Boot主动加载。模板文件放在 src/main/resources/templates/ 目次下,FreeMarker会主动处置惩罚这些文件。
  1. @Configuration
  2. public class FreeMarkerConfig {
  3.     @Value("${spring.freemarker.prefix:classpath:/templates/}")
  4.     private String freemarkerTemplatePrefix;
  5.     @Bean
  6.     public Configuration freemarkerConfiguration() {
  7.         Configuration configuration = new Configuration(Configuration.VERSION_2_3_31);
  8.         try {
  9.             configuration.setDirectoryForTemplateLoading(new File(freemarkerTemplatePrefix));
  10.         } catch (IOException e) {
  11.             e.printStackTrace();
  12.         }
  13.         configuration.setDefaultEncoding("UTF-8");
  14.         return configuration;
  15.     }
  16. }
复制代码
2. 模板文件(template.ftl)

模板文件内容,放在 src/main/resources/templates/ 目次下:
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <title>${title}</title>
  5. </head>
  6. <body>
  7.     <h1>${title}</h1>
  8.     <p>${content}</p>
  9. </body>
  10. </html>
复制代码
3. 图片路径(seal.png)

将章图片 seal.png 放在 src/main/resources/static/images/ 目次下。Spring Boot会主动处置惩罚这些资源,你可以通过类加载器获取并加载它。
4. PDF生成逻辑(PDFGenerator.java)

改进后的 PDFGenerator.java,支持动态加载模板和图片,生成带章的PDF文件,并灵活调整章的位置。
  1. package com.example.demo;
  2. import com.itextpdf.text.*;
  3. import com.itextpdf.text.pdf.PdfWriter;
  4. import com.itextpdf.text.Image;
  5. import freemarker.template.Configuration;
  6. import freemarker.template.Template;
  7. import freemarker.template.TemplateException;
  8. import org.springframework.stereotype.Service;
  9. import java.io.*;
  10. import java.util.HashMap;
  11. import java.util.Map;
  12. @Service
  13. public class PDFGenerator {
  14.     public void generatePdfWithSeal(String outputPdfPath, String sealImagePath) {
  15.         try {
  16.             // 模板数据
  17.             Map<String, Object> dataModel = new HashMap<>();
  18.             dataModel.put("title", "带章的PDF文件");
  19.             dataModel.put("content", "这是一份动态生成的带章PDF文件。");
  20.             // FreeMarker模板文件路径
  21.             String templateFile = "template.ftl";
  22.             // 创建FreeMarker配置
  23.             Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
  24.             cfg.setClassForTemplateLoading(PDFGenerator.class, "/templates");  // 设置模板目录
  25.             Template template = cfg.getTemplate(templateFile);
  26.             // 使用FreeMarker处理模板
  27.             StringWriter stringWriter = new StringWriter();
  28.             template.process(dataModel, stringWriter);
  29.             String generatedText = stringWriter.toString();
  30.             // 创建PDF文件
  31.             createPdfWithSeal(outputPdfPath, generatedText, sealImagePath);  // 图片路径
  32.         } catch (Exception e) {
  33.             e.printStackTrace();
  34.         }
  35.     }
  36.     private void createPdfWithSeal(String outputPdfPath, String text, String sealImagePath) throws Exception {
  37.         // 创建一个空的PDF文件
  38.         OutputStream outputStream = new FileOutputStream(outputPdfPath);
  39.         Document document = new Document();
  40.         PdfWriter writer = PdfWriter.getInstance(document, outputStream);
  41.         document.open();
  42.         // 添加内容
  43.         document.add(new Paragraph(text));
  44.         // 通过类加载器加载章图片(解决WAR包内路径问题)
  45.         InputStream sealInputStream = getClass().getClassLoader().getResourceAsStream(sealImagePath);
  46.         if (sealInputStream != null) {
  47.             Image sealImage = Image.getInstance(sealInputStream);
  48.             // 获取PDF页面的大小,并动态调整章位置
  49.             Rectangle pageSize = writer.getPageSize();
  50.             float x = pageSize.getWidth() - 150;  // 章离右边缘150px
  51.             float y = pageSize.getHeight() - 150;  // 章离下边缘150px
  52.             sealImage.setAbsolutePosition(x, y);
  53.             sealImage.scaleToFit(100, 100);  // 调整章的大小
  54.             document.add(sealImage);
  55.         } else {
  56.             System.err.println("章文件未找到:" + sealImagePath);
  57.         }
  58.         document.close();
  59.         outputStream.close();
  60.     }
  61. }
复制代码
5. Spring Boot Controller(PDFController.java)

为了便于测试并下载生成的PDF文件,创建一个REST接口,返回PDF文件流。
  1. package com.example.demo;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.http.HttpHeaders;
  4. import org.springframework.http.MediaType;
  5. import org.springframework.http.ResponseEntity;
  6. import org.springframework.web.bind.annotation.GetMapping;
  7. import org.springframework.web.bind.annotation.RestController;
  8. import java.io.File;
  9. import java.io.IOException;
  10. import java.nio.file.Files;
  11. @RestController
  12. public class PDFController {
  13.     @Autowired
  14.     private PDFGenerator pdfGenerator;
  15.     @GetMapping("/generate-pdf")
  16.     public ResponseEntity<byte[]> generatePdf() throws IOException {
  17.         String outputPdfPath = "output.pdf";
  18.         String sealImagePath = "images/seal.png";  // 章图片路径
  19.         // 调用PDF生成方法
  20.         pdfGenerator.generatePdfWithSeal(outputPdfPath, sealImagePath);
  21.         File generatedFile = new File(outputPdfPath);
  22.         if (generatedFile.exists()) {
  23.             byte[] fileContent = Files.readAllBytes(generatedFile.toPath());
  24.             // 返回PDF文件作为下载
  25.             return ResponseEntity.ok()
  26.                     .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="output.pdf"")
  27.                     .contentType(MediaType.APPLICATION_PDF)
  28.                     .body(fileContent);
  29.         } else {
  30.             return ResponseEntity.status(500).body(null);
  31.         }
  32.     }
  33. }
复制代码
6. Spring Boot配置(application.properties)

确保配置了FreeMarker模板的正确路径,配置如下:
  1. spring.freemarker.prefix=classpath:/templates/
  2. spring.freemarker.suffix=.ftl
  3. spring.freemarker.charset=UTF-8
复制代码
7. 静态资源存放路径

将seal.png放在src/main/resources/static/images/目次下,如许Spring Boot会主动处置惩罚和提供访问。
8. 目次布局

确保项目目次布局如下:
  1. src/
  2.   main/
  3.     java/
  4.       com/
  5.         example/
  6.           demo/
  7.             PDFGenerator.java         // PDF生成逻辑
  8.             PDFController.java        // REST控制器
  9.             DemoApplication.java      // Spring Boot启动类
  10.     resources/
  11.       static/
  12.         images/
  13.           seal.png                  // 章图片
  14.       templates/
  15.         template.ftl                // FreeMarker模板
  16.       application.properties        // Spring Boot配置文件
复制代码
9. 运行项目


  • 启动项目:运行Spring Boot应用步伐,可以使用下令:
    1. mvn spring-boot:run
    复制代码
  • 访问接口:打开欣赏器或使用Postman访问:
    1. http://localhost:8080/generate-pdf
    复制代码
    这会触发PDF生成并返回下载链接。
10. 测试与调试


  • 如果PDF文件生成成功,它会主动作为附件下载。
  • 如果出现问题,查抄控制台日记,确保:

    • 图片路径正确。
    • 模板路径正确。
    • PDF文件生成没有错误。



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

知者何南

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表