我有一个大单个pdf文档,它由多个记录组成。每个记录通常占用一页,但有些使用2页。记录以定义的文本开头,始终相同。
我的目标是将此pdf 拆分为单独的pdf文件,并且应该在找到“标题文本”之前进行拆分。
注意:我正在寻找使用java或python的工具或库。必须是免费的Win 7
。
有什么想法吗? AFAIK imagemagick
不适用于此。可以itext
这样做吗?我从来没用过它
非常复杂所以需要一些提示。
编辑:
标记答案让我解决了问题。为了完整性,我的确切实施:
public void splitByRegex(String filePath, String regex,
String destinationDirectory, boolean removeBlankPages) throws IOException,
DocumentException {
logger.entry(filePath, regex, destinationDirectory);
destinationDirectory = destinationDirectory == null ? "" : destinationDirectory;
PdfReader reader = null;
Document document = null;
PdfCopy copy = null;
Pattern pattern = Pattern.compile(regex);
try {
reader = new PdfReader(filePath);
final String RESULT = destinationDirectory + "/record%d.pdf";
// loop over all the pages in the original PDF
int n = reader.getNumberOfPages();
for (int i = 1; i < n; i++) {
final String text = PdfTextExtractor.getTextFromPage(reader, i);
if (pattern.matcher(text).find()) {
if (document != null && document.isOpen()) {
logger.debug("Match found. Closing previous Document..");
document.close();
}
String fileName = String.format(RESULT, i);
logger.debug("Match found. Creating new Document " + fileName + "...");
document = new Document();
copy = new PdfCopy(document,
new FileOutputStream(fileName));
document.open();
logger.debug("Adding page to Document...");
copy.addPage(copy.getImportedPage(reader, i));
} else if (document != null && document.isOpen()) {
logger.debug("Found Open Document. Adding additonal page to Document...");
if (removeBlankPages && !isBlankPage(reader, i)){
copy.addPage(copy.getImportedPage(reader, i));
}
}
}
logger.exit();
} finally {
if (document != null && document.isOpen()) {
document.close();
}
if (reader != null) {
reader.close();
}
}
}
private boolean isBlankPage(PdfReader reader, int pageNumber)
throws IOException {
// see http://itext-general.2136553.n4.nabble.com/Detecting-blank-pages-td2144877.html
PdfDictionary pageDict = reader.getPageN(pageNumber);
// We need to examine the resource dictionary for /Font or
// /XObject keys. If either are present, they're almost
// certainly actually used on the page -> not blank.
PdfDictionary resDict = (PdfDictionary) pageDict.get(PdfName.RESOURCES);
if (resDict != null) {
return resDict.get(PdfName.FONT) == null
&& resDict.get(PdfName.XOBJECT) == null;
} else {
return true;
}
}
答案 0 :(得分:5)
您可以使用iText为您的要求创建工具。
每当您查找有关iText库(当前版本)的代码示例时,您应该查看iText in Action — 2nd Edition代码示例,这些代码示例可以在线访问,并可以通过here中的关键字进行搜索。
在您的情况下,相关示例为Burst.java和ExtractPageContentSorted2.java。
Burst.java显示了如何在多个较小的PDF中拆分一个PDF。中央代码:
PdfReader reader = new PdfReader("allrecords.pdf");
final String RESULT = "record%d.pdf";
// We'll create as many new PDFs as there are pages
Document document;
PdfCopy copy;
// loop over all the pages in the original PDF
int n = reader.getNumberOfPages();
for (int i = 0; i < n; ) {
// step 1
document = new Document();
// step 2
copy = new PdfCopy(document,
new FileOutputStream(String.format(RESULT, ++i)));
// step 3
document.open();
// step 4
copy.addPage(copy.getImportedPage(reader, i));
// step 5
document.close();
}
reader.close();
此示例将PDF拆分为单页PDF。在您的情况下,您需要按不同的标准拆分。但这只意味着在循环中你有时必须添加多个导入的页面(从而将循环索引和页码分离以导入)。
要识别新数据集的哪些页面,请启发ExtractPageContentSorted2.java。此示例显示如何将页面的文本内容解析为字符串。中央代码:
PdfReader reader = new PdfReader("allrecords.pdf");
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
System.out.println("\nPage " + i);
System.out.println(PdfTextExtractor.getTextFromPage(reader, i));
}
reader.close();
只需搜索记录开始文本:如果页面中的文本包含它,则会从那里开始新记录。
答案 1 :(得分:1)
Apache PDFBox有一个PDFSplit实用程序,您可以从命令行运行。
答案 2 :(得分:1)
如果你喜欢Python,那就是一个很好的库:PyPDF2。该库是纯python2,类似BSD的许可证。
示例代码:
from PyPDF2 import PdfFileWriter, PdfFileReader
input1 = PdfFileReader(open("C:\\Users\\Jarek\\Documents\\x.pdf", "rb"))
# analyze pdf data
print input1.getDocumentInfo()
print input1.getNumPages()
text = input1.getPage(0).extractText()
print text.encode("windows-1250", errors='backslashreplacee')
# create output document
output = PdfFileWriter()
output.addPage(input1.getPage(0))
fout = open("c:\\temp\\1\\y.pdf", "wb")
output.write(fout)
fout.close()
答案 3 :(得分:0)
对于非编码人员,PDF Content Split可能是最简单的方法,无需重新发明轮子,并且界面易于使用:http://www.traction-software.co.uk/pdfcontentsplitsa/index.html
希望有所帮助。