我正在尝试使用 itext7 将多个生成的 pdf 从 servlet 放入 zip 中,我已成功将一个 pdf 放入 zip 文件中,但不能放入更多。这是代码:
private void printMore(HttpServletRequest req, HttpServletResponse resp) throws SQLException {
String masterPath = req.getServletContext().getRealPath("/assets/template/templateStatement.pdf");
try (PdfReader reader = new PdfReader(masterPath);
ZipOutputStream zipFile = new ZipOutputStream(resp.getOutputStream());
PdfWriter writer = new PdfWriter(zipFile);
PdfDocument pdf = new PdfDocument(reader, writer);
Document doc = new Document(pdf)) {
List<Student> studentList = getFactoryDAO().getStatementDAO().selectStudentHasBalance();
for (Student student : studentList){
// Generate PDF for the student
PdfPage page = pdf.getPage(1);
PdfCanvas canvas = new PdfCanvas(page);
FontProgram fontProgram = FontProgramFactory.createFont();
PdfFont font = PdfFontFactory.createFont(fontProgram, "utf-8", true);
canvas.setFontAndSize(font, 10);
canvas.beginText();
canvas.setTextMatrix(178, 650); // student code
canvas.showText(student.getS_Code());
canvas.setTextMatrix(200, 610); // Date of Statement
canvas.showText(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
canvas.endText();
float[] pointsWidth = {60f,120f,70f,70f};
Table table = new Table(pointsWidth);
table.setMarginTop(280);
table.setMarginLeft(70);
table.setFont(font);
table.setFontSize(10);
table.setTextAlignment(TextAlignment.CENTER);
//Header Table
table.addCell(new Cell().add("Date Inscription"));
table.addCell(new Cell().add("Name"));
table.addCell(new Cell().add("Fees"));
table.addCell(new Cell().add("Observation"));
//Detail Table
table.addCell(new Cell().add(student.getTxnDate()));
table.addCell(new Cell().add(student.getS_FullName));
table.addCell(new Cell().add(student.getFees));
table.addCell(new Cell().add(student.getObservation));
doc.add(table);
ZipEntry zipEntry = new ZipEntry(student.getS_Code() + "_" + student.getS_LName() + ".pdf");
zipFile.putNextEntry(zipEntry);
//zipFile.write(); Shall I use it?
}
} catch (IOException e) {
e.printStackTrace();
}
resp.setHeader("Content-disposition","attachement; filename=test.zip");
resp.setContentType("application/zip");
}
我基于此这篇文章和这篇文章,但不起作用。我已经检查了更多像 this 这样的帖子,但是 itext7 的版本没有提到的 PdfWriter.getInstance 。我尝试了更多的事情,但无法进一步。
更新:
根据 Enterman 的建议,我更新了它:
String masterPath = req.getServletContext().getRealPath("/assets/template/templateStatement.pdf");
try (PdfReader reader = new PdfReader(masterPath);
ZipOutputStream zipFile = new ZipOutputStream(resp.getOutputStream());
PdfWriter writer = new PdfWriter(zipFile);
PdfDocument pdf = new PdfDocument(reader, writer)
) {
List<Student> studentList = getFactoryDAO().getStatementDAO().selectStudentHasBalance();
for (Student student : studentList){
try (Document doc = new Document(pdf)){
// Generate PDF for the student
PdfPage page = pdf.getPage(1);
PdfCanvas canvas = new PdfCanvas(page);
FontProgram fontProgram = FontProgramFactory.createFont();
PdfFont font = PdfFontFactory.createFont(fontProgram, "utf-8", true);
canvas.setFontAndSize(font, 10);
canvas.beginText();
canvas.setTextMatrix(178, 650); // student code
canvas.showText(student.getS_Code());
canvas.setTextMatrix(200, 610); // Date of Statement
canvas.showText(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
canvas.endText();
float[] pointsWidth = {60f,120f,70f,70f};
Table table = new Table(pointsWidth);
table.setMarginTop(280);
table.setMarginLeft(70);
table.setFont(font);
table.setFontSize(10);
table.setTextAlignment(TextAlignment.CENTER);
//Header Table
table.addCell(new Cell().add("Date Inscription"));
table.addCell(new Cell().add("Name"));
table.addCell(new Cell().add("Fees"));
table.addCell(new Cell().add("Observation"));
//Detail Table
table.addCell(new Cell().add(student.getTxnDate()));
table.addCell(new Cell().add(student.getS_FullName));
table.addCell(new Cell().add(student.getFees));
table.addCell(new Cell().add(student.getObservation));
doc.add(table);
ZipEntry zipEntry = new ZipEntry(student.getS_Code() + "_" + student.getS_LName() + ".pdf");
zipFile.putNextEntry(zipEntry);
//zipFile.write(); Shall I use it?
}
}
} catch (IOException e) {
e.printStackTrace();
}
resp.setHeader("Content-disposition","attachement; filename=test.zip");
resp.setContentType("application/zip");
但还是没有运气。
欢迎您的帮助。
您应该尝试使用 FileInputStream,如下所示(我自己的代码,在生产中运行良好)
private File createZip(List<File> forZip, LocalDate date) {
String zipName = Constants.ORDER_FILE_PATH + date.getYear() +"-" + date.getMonth().getValue() + "-" + date.getMonth().getDisplayName(TextStyle.FULL, Locale.FRENCH) + ".zip";
FileOutputStream fos = null;
try {
fos = new FileOutputStream(zipName);
ZipOutputStream zipOut = new ZipOutputStream(fos);
for (File srcFile : forZip) {
FileInputStream fis = new FileInputStream(srcFile);
ZipEntry zipEntry = new ZipEntry(srcFile.getName());
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
fis.close();
//srcFile.delete();
}
zipOut.close();
fos.close();
} catch (IOException e) {
logger.error("createZip", e);
}
return new File(zipName);
}
特别感谢 BenjaminD、Enterman 和所有堆栈社区的支持。
我为那些和我遇到同样问题的人发布这个答案。 (我已经被困了4天了)。 “使用 itext 7 和 servlet 生成多个 PDF”
正如 Enterman 所说:“需要新的文档实例”。另外还需要PdfDocument。正如 BenjaminD 的指示:“首先生成 PDF 文件,然后将它们放入 zip 中”。
String masterPath = req.getServletContext().getRealPath("/assets/template/templateStatement.pdf");
try (ZipOutputStream zipOut = new ZipOutputStream(resp.getOutputStream())) {
Liste<File> listFile = new ArrayList<>();
List<Student> studentList = getFactoryDAO().getStatementDAO().selectStudentHasBalance();
for (Student student : studentList){
File file = new File(student.getS_Code()+"_"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".pdf");
try (PdfDocument pdf = new PdfDocument(new PdfReader(masterPath), new PdfWriter(file.getName()))
Document doc = new Document(pdf)){
// Generate PDF for the student
PdfPage page = pdf.getPage(1);
PdfCanvas canvas = new PdfCanvas(page);
FontProgram fontProgram = FontProgramFactory.createFont();
PdfFont font = PdfFontFactory.createFont(fontProgram, "utf-8", true);
canvas.setFontAndSize(font, 10);
canvas.beginText();
canvas.setTextMatrix(178, 650); // student code
canvas.showText(student.getS_Code());
canvas.setTextMatrix(200, 610); // Date of Statement
canvas.showText(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
canvas.endText();
float[] pointsWidth = {60f,120f,70f,70f};
Table table = new Table(pointsWidth);
table.setMarginTop(280);
table.setMarginLeft(70);
table.setFont(font);
table.setFontSize(10);
table.setTextAlignment(TextAlignment.CENTER);
//Header Table
table.addCell(new Cell().add("Date Inscription"));
table.addCell(new Cell().add("Name"));
table.addCell(new Cell().add("Fees"));
table.addCell(new Cell().add("Observation"));
//Detail Table
table.addCell(new Cell().add(student.getTxnDate()));
table.addCell(new Cell().add(student.getS_FullName));
table.addCell(new Cell().add(student.getFees));
table.addCell(new Cell().add(student.getObservation));
doc.add(table);
listFile.add(file);
}
}
File zipFile = createZip(listFile,
newSimpleDateFormat("yyyy-MM-dd").format(new Date())); //BenjaminD source in answer
ZipEntry zipEntry = new ZipEntry(zipFile.getName);
zipEntry.putNextEntry(zipEntry);
fileInputStream fis = new FileInputStream(zipFile);
byte[] bytes = new byte[1024];
int length;
while((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
fis.close();
resp.setHeader("Content-disposition","attachement; filename=" + zipFile);
resp.setContentType("application/zip");
} catch (IOException e) {
e.printStackTrace();
}
它将把 zip 放入 zip 中(可以直接使用 FileOutpuStream 不再将其放入 zip 中)。
再次感谢您。
对于任何想知道该解决方案是否可以使用 OpenPDF 而不是 itext 工作的人,kizawa 带来的内容可以进行调整并且它可以工作。
我写的代码是这样的:
public boolean generateMultiple(HttpServletResponse response, User user, List<Chat> closedChats) throws IOException {
try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
Account account = user.getAccount();
List<File> listFile = new ArrayList<>();
for (Chat chat : closedChats){
String endDate = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(chat.getEndDate());
File file = new File("transcript_" +
account.getName().replaceAll(" ", "_") +
"_" + endDate + "_" +
chat.getVisitor().getName().replaceAll(" ", "_") + ".pdf");
Document document = new Document(PageSize.A4);
PdfWriter.getInstance(document, new FileOutputStream(file));
document.open();
Paragraph title = new Paragraph(account.getName() + " - " + "Chat Transcript", new Font(Font.HELVETICA, 20, Font.BOLD));
title.setAlignment(Paragraph.ALIGN_CENTER);
title.setSpacingAfter(10);
PdfPTable header = getHeader(chat);
document.add(title);
document.add(header);
addMessages(chat, document);
document.addTitle(file.getName());
document.close();
listFile.add(file);
}
File zipFile = createZip(listFile, account);
ZipEntry zipEntry = new ZipEntry(zipFile.getName());
zipOut.putNextEntry(zipEntry);
FileInputStream fis = new FileInputStream(zipFile);
byte[] bytes = new byte[1024];
int length;
while((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
fis.close();
response.setHeader("Content-disposition","attachement; filename=" + zipFile);
response.setContentType("application/zip");
if(!zipFile.delete()){
logger.info("generateMultiple() | file {} was not deleted", zipFile.getName());
}
} catch (IOException e) {
logger.error("Invalid Input", e);
}
return true;
}
使用与 BenjaminD 相同但稍作修改的
createZip()
:
private File createZip(List<File> forZip, Account account) {
String zipName = account.getName().replaceAll(" ", "_") + "_transcript" + ".zip";
FileOutputStream fos;
try {
fos = new FileOutputStream(zipName);
ZipOutputStream zipOut = new ZipOutputStream(fos);
for (File srcFile : forZip) {
FileInputStream fis = new FileInputStream(srcFile);
ZipEntry zipEntry = new ZipEntry(srcFile.getName());
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
fis.close();
if(!srcFile.delete()){
logger.info("createZip() | file {} was not deleted", srcFile.getName());
}
}
zipOut.closeEntry();
zipOut.close();
fos.close();
} catch (IOException e) {
logger.error("createZip()", e);
}
return new File(zipName);
}