【Util】iText,iTextAsian,中文显示

本文详细介绍了如何使用iText库在Java中创建包含中文的PDF文档,并通过设置CMYK颜色来调整文本颜色。具体步骤包括路径获取字体、配置字体属性及颜色,以及在PDF中添加文本。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.youkuaiyun.com/inforstack/article/details/47083251

1.根据路径获取:

Font fontZh = FontFactory.getFont("C:\\Windows\\Fonts\\MSYH.TTF", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);

2.使用iTextAsian.jar中的字体

Font fontZh = FontFactory.getFont("STSong-Light", "UniGB-UCS2-H", 14, Font.BOLD, new CMYKColor(0, 255, 0, 0));

3.TestPDF.java

public static void main(String[] args) {
	try {
		Document document = new Document();
		OutputStream os = new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\test.pdf"));
		PdfWriter.getInstance(document, os);
		document.open();
		document.add(new Paragraph("看看有没有输出中文?", getFont()));
		document.close();
	} catch (Exception e) {
		e.printStackTrace();
	}
}


 

注:

1.个人习惯用FontFactory,FontFactory只不过对BaseFont进行了封装(个人理解,不喜勿喷)。FontFactory.getFont()中最后的实现还是调用了BaseFont.createFont();

2.jar包地址:http://download.youkuaiyun.com/detail/inforstack/8936407

<think>我们被要求使用Spring Boot和iText库根据模板生成PDF文件。根据引用[2],我们可以使用Adobe Acrobat Pro DC创建PDF模板,然后在Spring Boot中使用iText填充数据。 步骤: 1. 使用Adobe Acrobat Pro DC创建模板:在PDF中创建表单域(文本域、复选框等),并命名每个域。保存为模板文件(例如:template.pdf)。 2. 将模板文件放入Spring Boot项目的资源目录(如:src/main/resources/templates/)。 3. 添加依赖:在pom.xml中添加iText依赖(注意:我们使用iText7,但根据引用[2]可能是使用iText5?这里我们以iText7为例,因为它是较新版本,但需要根据实际情况选择。如果引用[2]中的模板是用Acrobat创建的,那么iText5和7都可以处理,但API不同。这里我们使用iText7,因为它是当前推荐版本,但请注意,如果用户使用的是旧版iText,可能需要调整代码)。 如果使用iText7,添加以下依赖(注意:iText7有多个模块): ```xml <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-core</artifactId> <version>7.2.5</version> <type>pom</type> </dependency> ``` 另外,我们还需要处理表单填充的模块,即`forms`模块: ```xml <dependency> <groupId>com.itextpdf</groupId> <artifactId>forms</artifactId> <version>7.2.5</version> </dependency> ``` 4. 编写服务类来生成PDF。 实现方法: 我们将创建一个PDF服务类,其中包含一个方法,该方法读取模板文件,然后使用PdfAcroForm来填充表单域,最后输出PDF。 注意:由于模板文件在资源目录中,我们需要使用ClassPathResource来读取。 代码示例: ```java import com.itextpdf.forms.PdfAcroForm; import com.itextpdf.forms.fields.PdfFormField; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfWriter; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Map; @Service public class PdfService { public void generatePdf(OutputStream outputStream, Map<String, String> formData) throws IOException { // 加载模板文件 ClassPathResource resource = new ClassPathResource("templates/template.pdf"); InputStream inputStream = resource.getInputStream(); // 初始化PdfReader和PdfWriter PdfReader reader = new PdfReader(inputStream); PdfWriter writer = new PdfWriter(outputStream); PdfDocument pdfDoc = new PdfDocument(reader, writer); // 获取表单 PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true); // 填充表单数据 Map<String, PdfFormField> fields = form.getFormFields(); for (Map.Entry<String, String> entry : formData.entrySet()) { String fieldName = entry.getKey(); String value = entry.getValue(); PdfFormField field = fields.get(fieldName); if (field != null) { field.setValue(value); } } // 如果不需要表单可编辑,可以将其扁平化(这样表单域就变成普通文本) form.flattenFields(); // 关闭文档 pdfDoc.close(); } } ``` 5. 在控制器中调用此服务,生成PDF并返回给前端预览(例如,通过HTTP响应)。 控制器示例: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.InputStreamResource; 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.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.HashMap; import java.util.Map; @RestController public class PdfController { @Autowired private PdfService pdfService; @GetMapping("/generatePdf") public ResponseEntity<InputStreamResource> generatePdf() throws IOException { // 模拟数据 Map<String, String> data = new HashMap<>(); data.put("name", "张三"); data.put("age", "30"); // 其他表单域数据... ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); pdfService.generatePdf(outputStream, data); byte[] pdfBytes = outputStream.toByteArray(); HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=generated.pdf"); return ResponseEntity .ok() .headers(headers) .contentType(MediaType.APPLICATION_PDF) .body(new InputStreamResource(new ByteArrayInputStream(pdfBytes))); } } ``` 这样,当访问/generatePdf时,就会生成PDF并在浏览器中预览。 注意事项: - 模板中的表单域名称必须与代码中使用的键一致。 - 如果需要生成多页,确保模板中已经设计好分页,并且表单域名称唯一(如果同一名称出现在多页,则都会被填充相同值)。 - 如果表单域是复选框,设置值应为"On"(或根据模板中定义的导出值)来勾选,否则为"Off"。 - 使用扁平化(flattenFields)后,表单域将变成静态内容,无法再编辑。如果不调用此方法,则生成的PDF表单仍可编辑。 以上代码基于iText7。如果使用iText5,代码会有所不同,但思路类似:使用PdfStamper和AcroFields。 如果用户需要使用iText5,那么依赖和代码将不同。这里给出iText5的依赖和代码片段(供参考): 依赖(iText5): ```xml <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.3</version> </dependency> ``` iText5代码示例(PdfService内): ```java import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.AcroFields; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import org.springframework.core.io.ClassPathResource; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Map; public byte[] generatePdfWithIText5(Map<String, String> formData) throws IOException, DocumentException { ClassPathResource resource = new ClassPathResource("templates/template.pdf"); InputStream inputStream = resource.getInputStream(); PdfReader reader = new PdfReader(inputStream); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PdfStamper stamper = new PdfStamper(reader, outputStream); AcroFields form = stamper.getAcroFields(); // 填充表单 for (Map.Entry<String, String> entry : formData.entrySet()) { String fieldName = entry.getKey(); String value = entry.getValue(); form.setField(fieldName, value); } // 如果扁平化,则表单域变成普通文本 stamper.setFormFlattening(true); stamper.close(); reader.close(); return outputStream.toByteArray(); } ``` 在控制器中调用即可。 总结:根据项目需求选择iText版本。本文提供了iText7和iText5两种实现方式,但推荐使用iText7,因为它是当前活跃开发的版本。 引用说明: [^1]: 介绍了Spring Boot和iTextPdf生成PDF的背景。 [^2]: 提供了使用PDF模板生成文件的方法,并提到了使用Adobe Acrobat Pro DC创建模板。 注意:上述代码仅为示例,实际应用中需要处理异常、资源关闭等。 生成相关问题: 1. 如何使用Adobe Acrobat Pro DC创建PDF表单模板? 2. 在Spring Boot中生成PDF时如何处理中文字体? 3. 如何动态生成多页PDF(例如根据列表数据生成多行)? 4. iText5和iText7的主要区别是什么?如何选择? 5. 除了iText,还有哪些Java库可以用于生成PDF?</think>### Spring Boot中使用iText库根据模板生成PDF文件的实现方法 在Spring Boot中使用iText库根据模板生成PDF文件,主要分为三个核心步骤: #### 1. **准备PDF模板** - 使用Adobe Acrobat Pro DC创建带表单域的PDF模板: - 添加文本域(命名如`name_field`、`date_field`) - 添加复选框/单选按钮(命名如`agree_checkbox`) - 将模板文件(如`template.pdf`)放入`src/main/resources/templates/`目录[^2] #### 2. **添加依赖** 在`pom.xml`中添加iText依赖(推荐iText 7+): ```xml <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-core</artifactId> <version>7.2.5</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>forms</artifactId> <version>7.2.5</version> </dependency> ``` #### 3. **核心代码实现** ```java @Service public class PdfGeneratorService { public byte[] generatePdfFromTemplate(Map<String, String> formData) throws IOException { // 1. 加载模板 ClassPathResource templateResource = new ClassPathResource("templates/template.pdf"); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try (PdfReader reader = new PdfReader(templateResource.getInputStream()); PdfWriter writer = new PdfWriter(outputStream); PdfDocument pdfDoc = new PdfDocument(reader, writer)) { // 2. 获取表单对象 PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true); // 3. 填充表单数据 formData.forEach((fieldName, value) -> { PdfFormField field = form.getField(fieldName); if (field != null) { field.setValue(value); } }); // 4. 扁平化表单(使字段不可编辑) form.flattenFields(); } return outputStream.toByteArray(); } } ``` #### 4. **控制器调用示例** ```java @RestController public class PdfController { @Autowired private PdfGeneratorService pdfService; @GetMapping("/generate-pdf") public ResponseEntity<byte[]> generatePdf() throws IOException { // 构建动态数据 Map<String, String> formData = new HashMap<>(); formData.put("name_field", "张三"); formData.put("date_field", "2023-10-15"); formData.put("agree_checkbox", "Yes"); byte[] pdfBytes = pdfService.generatePdfFromTemplate(formData); // 设置响应头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_PDF); headers.setContentDisposition(ContentDisposition.inline().filename("output.pdf").build()); return new ResponseEntity<>(pdfBytes, headers, HttpStatus.OK); } } ``` #### 关键注意事项: 1. **表单域匹配** 模板中的字段名称必须与代码中的`fieldName`完全一致(区分大小写) 2. **中文支持** 需添加中文字体依赖: ```xml <dependency> <groupId>com.itextpdf</groupId> <artifactId>font-asian</artifactId> <version>7.2.5</version> </dependency> ``` 在填充前设置字体: ```java PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H"); field.setFont(font); ``` 3. **动态表格处理** 如需在模板外追加动态内容(如表格),可在扁平化后添加新页面: ```java PdfPage newPage = pdfDoc.addNewPage(); try (Canvas canvas = new Canvas(newPage, pdfDoc.getDefaultPageSize())) { canvas.add(new Paragraph("动态表格").setFont(font)); // 添加表格逻辑... } ``` 4. **性能优化** - 使用`ByteArrayOutputStream`避免磁盘I/O - 模板文件预加载到内存(适用于高频调用) - 对于复杂模板,考虑使用`PdfDocument`的增量更新模式 [^1]: 在现代应用程序开发中,生成PDF文件是一个常见的需求... [^2]: SpringBoot 基于iText 根据PDF模板动态生成文件... --- ### 相关问题 1. **如何处理PDF模板中的动态表格数据?** 当需要在模板基础上追加动态表格时,应如何实现行列数据的灵活生成? 2. **如何解决iText生成PDF的中文乱码问题?** 使用中文字体时有哪些注意事项?不同操作系统下字体配置有何差异? 3. **在微服务架构中如何优化PDF生成性能?** 高并发场景下有哪些缓存策略和资源复用方案? 4. **如何实现PDF模板的动态版本管理?** 当业务需要频繁更新模板时,如何设计版本控制系统? 5. **除了iText,还有哪些Java库支持模板化PDF生成?** 如Apache PDFBox、Flying Saucer等替代方案的优缺点比较。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值