英文:
generate zip file grouping multiple pdf, using servlet and itext 7
问题
以下是你提供的代码的翻译部分:
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) {
// 为学生生成PDF
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); // 学生编号
canvas.showText(student.getS_Code());
canvas.setTextMatrix(200, 610); // 生成日期
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);
// 表头
table.addCell(new Cell().add("报名日期"));
table.addCell(new Cell().add("姓名"));
table.addCell(new Cell().add("费用"));
table.addCell(new Cell().add("备注"));
// 表格内容
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(); 是否需要使用它?
}
} catch (IOException e) {
e.printStackTrace();
}
resp.setHeader("Content-disposition", "attachment; filename=test.zip");
resp.setContentType("application/zip");
}
在代码中,我保留了你提供的注释和代码逻辑,只是将代码翻译成了中文。如果你有任何问题或需要进一步帮助,请随时提问。
英文:
I'm trying to put multiple generated pdf into a zip from servlet using itext7, I've managed to put one pdf in a zip file but not more. Here is the code:
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");
}
I've based on this this post and this post but doesn't work. I already check more post like this but the version of itext7 has no PdfWriter.getInstance as mentionned. I've tried more thing but can't managed to go furthermore.
UPDATED :
After Enterman suggestion i updated it like this :
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");
But still no luck.
Your help is welcome.
答案1
得分: 1
你应该尝试使用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);
}
英文:
You should try using a FileInputStream, like below (code of my own, working well in production)
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);
}
答案2
得分: 0
特别感谢BenjaminD和Enterman的支持,以及所有的堆栈社区。
我发布这个答案是为了那些遇到和我一样问题的人。(我被困了4天)。"使用itext 7和servlet生成多个PDF"
正如Enterman所说:"需要新的Document实例"。此外还需要PdfDocument。还有根据BenjaminD的指示:"首先生成PDF文件,然后将它们放入一个zip文件中"。
String masterPath = req.getServletContext().getRealPath("/assets/template/templateStatement.pdf");
try (ZipOutputStream zipOut = new ZipOutputStream(resp.getOutputStream())) {
List<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)) {
// 为学生生成PDF
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); // 学生代码
canvas.showText(student.getS_Code());
canvas.setTextMatrix(200, 610); // 对账单日期
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);
// 表头
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"));
// 表格内容
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, new SimpleDateFormat("yyyy-MM-dd").format(new Date())); // BenjaminD的回答中的源代码
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();
resp.setHeader("Content-disposition", "attachement; filename=" + zipFile);
resp.setContentType("application/zip");
} catch (IOException e) {
e.printStackTrace();
}
它将把zip文件放入另一个zip文件中(可以直接使用FileOutputStream,而不必再次放入zip文件中)。
再次感谢。
英文:
Special thanks for BenjaminD, Enterman for their support and all stack community.
I post this answer for those who has faced the same problem as me. (I've been stuck for 4 days). "Generating multiple PDF with itext 7 and servlets"
As Enterman said : "need new Instance of Document". In addition need PdfDocument also. And as BenjaminD instruction : "Generate a file PDF first, after put them into a 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();
}
It will put the zip in a zip (can Directly use FileOutpuStream to not put it again in a zip).
Thank you again.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论