我有一个例程,我反复为许多项目做,我想概括它。我使用iText
进行PDF操作。
假设我在一个文件夹中有2000个PDF,我需要将它们压缩在一起。假设每个拉链的限制为1000个PDF。因此,zip的名称将遵循此规则:job name
+ job sequence
。例如,前1000张PDF的zip名称为XNKXMN
+ AA
,第二个zip名称为XNKXMN
+ AB
。在压缩这些PDF之前,我需要为每个PDF添加一些文本。文字看起来像job name
+ job sequence
+ pdf sequence
。因此,第一个 zip中的第一个PDF将包含此文XNKXMN
+ AA
+ 000001
,之后的XNKXMN
+ { {1}} + AA
。这是我的尝试
首先,我有抽象的句子000002
代表我的文字。
GenericText
public abstract class GenericText {
private float x;
private float y;
private float rotation;
/**
* Since the text that the user want to insert onto the Pdf might vary
* from page to page, or from logical document to logical document, we allow
* the user to write their own implementation of the text. To give the user enough
* flexibility, we give them the reference to the physical page index, the logical page index.
* @param physcialPage The actual page number that the user current looking at
* @param logicalPage A Pdf might contain multiples sub-documents, <code>logicalPage</code>
* tell the user which logical sub-document the system currently looking at
*/
public abstract String generateText(int physicalPage, int logicalPage);
GenericText(float x, float y, float rotation){
this.x = x;
...
}
}
:我的通用API,用于执行上述操作
JobGenerator.java
所以现在在我的主要班级我会这样做
public String generatePrintJob(List<File> pdfList, String outputPath,
String printName, String seq, List<GenericText> textList, int maxSize)
for (int currentPdfDocument = 0; currentPdfDocument < pdfList.size(); currentPdfDocument++) {
File pdf = pdfList.get(currentPdfDocument);
if (currentPdfDocument % maxSize != 0) {
if(textList != null && !textList.isEmpty()){
for(GenericText gt : textList){
String text = gt.generateText(currentPdfDocument, currentPdfDocument)
//Add the text content to the PDF using PdfReader and PdfWriter
}
}
...
}else{
//Close the current output stream and zip output stream
seq = Utils.getNextSeq(seq);
jobPath = outputPath + File.separator + printName + File.separator + seq + ".zip"
//Open new zip output stream with the new <code>jobPath</code>
}
}
}
我对此设计的问题是,即使我将PDF正确存档到两个zip文件中,文本也没有正确反映。打印和序列不会相应更改,对于前1000个而言,对于2000 PDF而不是final String printName = printNameLookup.get(baseOutputName);
String jobSeq = config.getPrintJobSeq();
final String seq = jobSeq;
GenericText keyline = new GenericText(90, 640, 0){
@Override
public String generateText(int physicalPage, int logicalPage) {
//if logicalPage = 1, Utils.right(String.valueOf(logicalPage), 6, '0') -> 000001
return printName + seq + " " + Utils.right(String.valueOf(logicalPage), 6, '0');
}
};
textList.add(keyline);
JobGenerator pjg = new JobGenerator();
pjg.generatePrintJob(...,..., printName, jobSeq, textList, 1000);
+ XNKXMN
保留AA
+ XNKXMN
并更改为{{1} } + AA
用于后来的1000. 我的设计似乎存在缺陷,请帮助
修改:
查看XNKXMN
代码后,我看到了我的问题。我创建AB
,希望在pdf页面的任何地方添加文本,而不会影响流程的基本逻辑。但是,作业顺序根据逻辑定义,因为如果一个ZIP要处理的PDF太多(&gt; toto2
),则需要递增。我需要重新考虑一下。
答案 0 :(得分:4)
当您创建匿名GenerateText
时,您在重写的final seq
方法中使用的generateText
确实是最终的,并且始终保持创建时给定的值。您在seq
else
内generatePrintJob
内进行的更新不会做任何事情。
更一般地说,您的代码看起来非常复杂,您应该退后一步并进行一些重大的重构。
修改强>:
我会尝试不同的东西,没有模板方法模式:
int numberOfZipFiles =
(int) Math.ceil((double) pdfList.size() / maxSize);
for (int iZip = 0; iZip < numberOfZipFiles; iZip++) {
String batchSubName = generateBatchSubName(iZip); // gives AA, AB,...
for (int iFile = 0; iFile < maxSize; iFile++) {
int fileNumber = iZip * maxSize + iFile;
if (fileNumber >= pdfList.size()) // can happen for last batch
return;
String text = jobName + batchSubName + iFile;
... add "text" to pdfList.get(fileNumber)
}
}
但是,您可能还想维护模板模式。在这种情况下,我会保留上面写的for循环,但我会将生成方法更改为genericText.generateText(iZip, iFile)
,其中iZip = 0给出AA,iZip = 1给出AB等等:
for (int iZip = 0; iZip < numberOfZipFiles; iZip++) {
for (int iFile = 0; iFile < maxSize; iFile++) {
int fileNumber = iZip * maxSize + iFile;
if (fileNumber >= pdfList.size()) // can happen for last batch
return;
String text = genericText.generateText(iZip, iFile);
... add "text" to pdfList.get(fileNumber)
}
}
也可能有genericText.generateText(fileNumber)
本身可以分解AA000001中的fileNumber等等。但这有点危险,因为maxSize会在两个不同的地方使用,并且可能容易出错这样的数据。