使用itextpdf解决PDF合并的问题

网友投稿 251 2022-12-30

使用itextpdf解决PDF合并的问题

itextpdf解决PDF合并的问题

本文章是我在项目开发过程中解决了一个关于PDF显示的需求而记录的。

需求是这样的,需要将两个PDF进行合并,一个PDF是根据数据库的信息在在后台形成的(实际不存在的PDF),另一个是磁盘保存的PDF文件(这个PDF文件后期会变成从云端获取)。

作为一个java菜鸟,这个问题解决了数天,还是在leader的指导下解决的。在这里做一下关键代码的记录。

项目主要包含了以下关键词:(我不做详解了,主要是用了这些)

- Spring MVC、Spring、Hibernate

- Maven

- Java

- itextpdf

- mysql

- JavaWeb相关

首先是itextpdf的依赖

com.itextpdf

itextpdf

5.5.10

如何在后台生成一个PDF

这个问题,百度上有很多解决方案,因为我需要将这个生成的PDF和已存在的PDF拼接,于是尝试了多种方案,决定将这个以文档的形式,将这个文档转为字节数组,然后用itextpdf将流读取到PDF中。

生成PDF的部分代码:

import java.io.ByteArrayOutputStream;

import com.model.User;

import com.itextpdf.text.BaseColor;

import com.itextpdf.text.Document;

import com.itextpdf.text.DocumentException;

import com.itextpdf.text.Element;

import com.itextpdf.text.Font;

import com.itextpdf.text.Paragraph;

import com.itextpdf.text.pdf.BaseFont;

import com.itextpdf.text.pdf.PdfContentByte;

import com.itextpdf.text.pdf.PdfPCell;

import com.itextpdf.text.pdf.PdfPTable;

import com.itextpdf.text.pdf.PdfReader;

import com.itextpdf.text.pdf.PdfWriter;

import com.itextpdf.text.pdf.parser.PdfReaderContentParser;

public class ReportKit {

public static byte[] createReport(User user) throws Exception {

ByteArrayOutputStream ba = new ByteArrayOutputStream();

Document doc = new Document();//创建一个document对象

PdfWriter writer = PdfWriter.getInstance(doc, ba);//这个PdfWriter会一直往文档里写内容。

doc.open();//开启文档

BaseFont bfChinese = BaseFont.createFont("c://windows//fonts//msyh.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

com.itextpdf.text.Font FontChinese18 = new com.itextpdf.text.Font(bfChinese, 18, com.itextpdf.text.Font.BOLD);

com.itextpdf.text.Font FontChinese12 = new com.itextpdf.text.Font(bfChinese, 12, com.itextpdf.text.Font.NORMAL);

com.itextpdf.text.Font FontChinese11 = new com.itextpdf.text.Font(bfChinese, 11, com.itextpdf.text.Font.ITALIC);

Font fontChinese = new Font(bfChinese , 12 , Font.NORMAL, BaseColor.BLACK);

Paragraph pf = new Paragraph("");

//加入空行

Paragraph blankRow1 = new Paragraph(24f," ",FontChinese18);

doc.add(blankRow1);

//table2

PdfPTable table25 = new PdfPTable(2);

//设置每列宽度比例

int width21[] = {2,98};

table25.setWidths(width21);

table25.getDefaultCell().setBorder(0);

PdfPCell cell25 = new PdfPCell(new Paragraph("这是一个报告",FontChinese18));

cell25.setBorder(0);

table25.addCell("");

table25.addCell(cell25);

doc.add(table25);

Paragraph blankRow3 = new Paragraph(18f, "Report ", FontChinese11);

blankRow3.setAlignment(PdfContentByte.ALIGN_RIGHT);

doc.add(blankRow3);

BaseColor lightGrey = new BaseColor(0xCC,0xCC,0xCC);

PdfPTable table8 = new PdfPTable(6);

//设置table的宽度为100%

table8.setWidthPercentage(100);

//设置不同列的宽度

float[] columnWidths = {1.6f, 1.6f, 1.6f, 1.6f, 1.6f, 1.6f};

table8.setWidths(columnWidths);

PdfPCell cell1 = new PdfPCell(new Paragraph("用户名",FontChinese12));

PdfPCell cell2 = new PdfPCell(new Paragraph("出生日期",FontChinese12));

PdfPCell cell3 = new PdfPCell(new Paragraph("性别",FontChinese12));

PdfPCell cell4 = new PdfPCell(new Paragraph("身高",FontChinese12));

PdfPCell cell5 = new PdfPCell(new Paragraph("体重",FontChinese12));

PdfPCell cell6 = new PdfPCell(new Paragraph("地区",FontChinese12));

PdfPCell cell7 = new PdfPCell(new Paragraph(user.getAccessname(),FontChinese12));

PdfPCell cell8 = new PdfPCell(new Paragraph(user.getBirthday(),FontChinese12));

PdfPCell cell9 = new PdfPCell(new Paragraph(sex,FontChinese12));

PdfPCell cell10 = new PdfPCell(new Paragraph(String.valueOf(user.getHeight()),FontChinese12));

PdfPCell cell11 = new PdfPCell(new Paragraph(String.valueOf(user.getWeight()),FontChinese12));

PdfPCell cell12 = new PdfPCell(new Paragraph(user.getArea_name(),FontChinese12));

//表格高度

cell1.setFixedHeight(30);

cell2.setFixedHeight(30);

cell3.setFixedHeight(30);

cell4.setFixedHeight(30);

cell5.setFixedHeight(30);

cell6.setFixedHeight(30);

cell7.setFixedHeight(30);

cell8.setFixedHeight(30);

cell9.setFixedHeight(30);

cell10.setFixedHeight(30);

cell11.setFixedHeight(30);

cell12.setFixedHeight(30);

//水平居中

cell1.setHorizontalAlignment(Element.ALIGN_CENTER);

cell2.setHorizontalAlignmhttp://ent(Element.ALIGN_CENTER);

cell3.setHorizontalAlignment(Element.ALIGN_CENTER);

cell4.setHorizontalAlignment(Element.ALIGN_CENTER);

cell5.setHorizontalAlignment(Element.ALIGN_CENTER);

cell6.setHorizontalAlignment(Element.ALIGN_CENTER);

cell7.setHorizontalAlignment(Element.ALIGN_CENTER);

cell8.setHorizontalAlignment(Element.ALIGN_CENTER);

cell9.setHorizontalAlignment(Element.ALIGN_CENTER);

cell10.setHorizontalAlignment(Element.ALIGN_CENTER);

cell11.setHorizontalAlignment(Element.ALIGN_CENTER);

cell12.setHorizontalAlignment(Element.ALIGN_CENTER);

//垂直居中

cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell4.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell5.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell6.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell7.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell8.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell9.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell10.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell11.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell12.setVerticalAlignment(Element.ALIGN_MIDDLE);

//边框颜色

cell1.setBorderColor(lightGrey);

cell2.setBorderColor(lightGrey);

cell3.setBorderColor(lightGrey);

cell4.setBorderColor(lightGrey);

cell5.setBorderColor(lightGrey);

cell6.setBorderColor(lightGrey);

cell7.setBorderColor(lightGrey);

cell8.setBorderColor(lightGrey);

cell9.setBorderColor(lightGrey);

cell10.setBorderColor(lightGrey);

cell11.setBorderColor(lightGrey);

cell12.setBorderColor(lightGrey);

table8.addCell(cell1);

table8.addCell(cell2);

table8.addCell(cell3);

table8.addCell(cell4);

table8.addCell(cell5);

table8.addCell(cell6);

table8.addCell(cell7);

table8.addCell(cell8);

table8.addCell(cell9);

table8.addCell(cell10);

table8.addCell(cell11);

table8.addCell(cell12);

doc.add(table8);

doc.close();//(有开启文档,就要记得关闭文档)

writer.close();

byte[] bytes = ba.toByteArray();

return bytes;

}

}

用document来编辑文档,真的蛮恶心的,费时费力,排版也不好调,如果能有更加好用的方式,希望大家能告诉我。

到这里,调用这个方法,就可以获得这个文档的字节数组了。

接下来开始拼接PDF。因为是结合前端页面实现的。因此这个方法是我在controller完成的。

//注意这里的produces,“application/pdf”,正是因为设置了这个,使得整个方法会将文档以PDF的格式返回到页面。

@RequestMapping(value = "/newPdf/{report_name}", produces = "application/pdf;charset=UTF-8")

public void updateReport(Model model, @PathVariable String report_name, HttpServletRequest request,

HttpServletResponse response,HttpSession session) {

try {

User user = (User) session.getAttribute("user");

//这是用户登录后保存到session里的用户信息(可以用别的对象来替代这个)

if(user==null){

return ;

}

PdfReader reader1 =null;

try {

// 调用刚刚写的生成PDF的方法,将这个字节数组获取。

byte[] pdfUserByte=ReportKit.createReport(user);

if(pdfUserByte==null||pdfUserByte.length==0){

return;

}

//用pdfReader来读取字节数组,这里将文档信息读入

reader1 = new PdfReader(pdfUserByte);

} catch (Exception e) {

System.out.println(e.getMessage());

return ;

}

if(reader1==null) return;

//第二个PDF的读取

PdfReader reader2;

// 报告的PDF

reader2 = new PdfReader("C:\\Users\\Administrator\\Desktop\\report.pdf");

Document document = new Dochttp://ument();

PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());

document.open();

PdfContentByte cb = writer.getDirectContent();

int totalPages = 0;

totalPages += reader1.getNumberOfPages();

totalPages += reader2.getNumberOfPages();

java.util.List readers = new ArrayList();

readers.add(reader1);

readers.add(reader2);

int pageOfCurrentReaderPDF = 0;

Iterator iteratorPDFReader = readers.iterator();

// Loop through the PDF files and add to the output.

while (iteratorPDFReader.hasNext()) {

PdfReader pdfReader = iteratorPDFReader.next();

// Create a new page in the target for each source page.

while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {

document.newPage();//创建新的一页

pageOfCurrentReaderPDF++;

PdfImportedPage page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);

cb.addTemplate(page, 0, 0);

}

pageOfCurrentReaderPDF = 0;

}

document.close();

writer.close();

} catch (IOException | DocumentException e) {

e.printStackTrace();

}

}

关于如何在页面预览这个PDF,我用了object标签来获取。

jsp上的部分片段

标签很好的实现了PDF预览的功能,如果是URL的PDF,data直接输入URL,就能将PDF在页面预览,感觉蛮好用的。

iText 合并PDF文件报错

在使用iText操作PDF进行合并的时候报错:

com.lowagie.text.exceptions.BadPasswordException: PdfReader not opened with owner password

public static PdfReader unlockPdf(PdfReader pdfReader) {

if (pdfReader == null) {

return pdfReader;

}

try {

java.lang.reflect.Field f = pdfReader.getClass().getDeclaredField("encrypted");

f.setAccessible(true);

f.set(pdfReader, false);

} catch (Exception e) {

// ignore

}

return pdfReader;

}

对reader使用上述方法即可解决该问题。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java实现图片上传至FastDFS入门教程
下一篇:网站的api接口有什么用(网站的api接口有什么用处)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~