4

我可以使用 pdfbox 获取大多数 pdf 文件的字段名称,但我无法获取字段所得税表。它是那种形式的限制。

尽管它在表单中包含多个字段,但它只显示一个字段。

这是输出:

最上面的子窗体[0]。

我的代码:

PDDocumentCatalog docCatalog = pdfDocument.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();
List fields = acroForm.getFields();

@SuppressWarnings("rawtypes")
java.util.Iterator fieldsIter = fields.iterator();
System.out.println(new Integer(fields.size()).toString());
while( fieldsIter.hasNext())
{
    PDField field = (PDField)fieldsIter.next();
    System.out.println(field.getFullyQualifiedName());
    System.out.println(field.getPartialName());
}

用于

public static void main(String[] args) throws IOException {
    PDDocument pdDoc = null;
    try {
        pdDoc = PDDocument.load("income.pdf");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace(); 
    }
    Ggdfgdgdgf feilds = new Ggdfgdgdgf();
    feilds.printFields(pdDoc);
}
4

3 回答 3

10

有问题的 PDF 是混合 AcroForm/XFA 表单。这意味着它包含 AcroForm 和 XFA 格式的表单定义。

PDFBox 主要支持 AcroForm(这是 PDF 规范中介绍的 PDF 表单技术),但由于两种格式都存在,PDFBox 至少可以检查 AcroForm 表单定义。

您的代码忽略AcroForm.getFields()不返回所有字段定义而仅返回根字段的定义,参见。JavaDoc 评论:

/**
 * This will return all of the documents root fields.
 * 
 * A field might have children that are fields (non-terminal field) or does not
 * have children which are fields (terminal fields).
 * 
 * The fields within an AcroForm are organized in a tree structure. The documents root fields 
 * might either be terminal fields, non-terminal fields or a mixture of both. Non-terminal fields
 * mark branches which contents can be retrieved using {@link PDNonTerminalField#getChildren()}.
 * 
 * @return A list of the documents root fields.
 * 
 */
public List<PDField> getFields()

如果要访问所有字段,则必须遍历表单字段树,例如:

public void test() throws IOException
{
    try (   InputStream resource = getClass().getResourceAsStream("f2290.pdf"))
    {
        PDDocument pdfDocument = PDDocument.load(resource);
        PDDocumentCatalog docCatalog = pdfDocument.getDocumentCatalog();
        PDAcroForm acroForm = docCatalog.getAcroForm();
        List<PDField> fields = acroForm.getFields();
        for (PDField field : fields)
        {
            list(field);
        }
    }
}

void list(PDField field)
{
    System.out.println(field.getFullyQualifiedName());
    System.out.println(field.getPartialName());
    if (field instanceof PDNonTerminalField)
    {
        PDNonTerminalField nonTerminalField = (PDNonTerminalField) field;
        for (PDField child : nonTerminalField.getChildren())
        {
            list(child);
        }
    }
}

这将为您的文档返回一个巨大的字段列表。

PS:您没有说明您使用的是哪个 PDFBox 版本。由于目前 PDFBox 开发显然已经开始推荐使用当前的 2.0.0 候选版本,我在回答中假设您使用该版本。

于 2016-02-29T11:08:33.703 回答
1

使用 fieldTree 可以更轻松地完成此操作

fun getFieldsInDocument(file: File): List<String> {
    return PDDocument.load(file).use { document ->
        document.documentCatalog.acroForm.fieldTree
                .filter { it is PDTerminalField }
                .map { field ->
                    field.fullyQualifiedName
                }
    }
}

这是 Kotlin,但在 Java 中看起来基本相同。

于 2018-09-24T12:18:49.783 回答
-1

这是阅读pdf的示例代码。在使用它之前,请设置您的输入PDF文件。

import java.io.File;
import java.io.FileInputStream;
import java.io.PrintWriter;
import org.apache.pdfbox.cos.COSDocument;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.util.PDFTextStripper;

public class JavaApplication14 {

    PDFParser parser;
    String parsedText;
    PDFTextStripper pdfStripper;
    PDDocument pdDoc;
    COSDocument cosDoc;
//    PDDocumentInformation pdDocInfo;
// PDFTextParser Constructor 
    public JavaApplication14() {
    }
// Extract text from PDF Document
    String pdftoText(String fileName) {
        System.out.println("Parsing text from PDF file " + fileName + "....");
        File f = new File(fileName);
        if (!f.isFile()) {
            System.out.println("File " + fileName + " does not exist.");
            return null;
        }
        try {
            parser = new PDFParser(new FileInputStream(f));
        } catch (Exception e) {
            System.out.println("Unable to open PDF Parser.");
            return null;
        }
        try {
            parser.parse();
            cosDoc = parser.getDocument();
            pdfStripper = new PDFTextStripper();
            pdDoc = new PDDocument(cosDoc);
            parsedText = pdfStripper.getText(pdDoc);
        } catch (Exception e) {
            System.out.println("An exception occured in parsing the PDF Document.");
            e.printStackTrace();
            try {
                if (cosDoc != null) {
                    cosDoc.close();
                }
                if (pdDoc != null) {
                    pdDoc.close();
                }
            } catch (Exception e1) {
                e.printStackTrace();
            }
            return null;
        }
        System.out.println("Done.");
        return parsedText;
    }
// Write the parsed text from PDF to a file
    void writeTexttoFile(String pdfText, String fileName) {
        System.out.println("\nWriting PDF text to output text file " + fileName + "....");
        try {
            PrintWriter pw = new PrintWriter(fileName);
            pw.print(pdfText);
            pw.close();
        } catch (Exception e) {
            System.out.println("An exception occured in writing the pdf text to file.");
            e.printStackTrace();
        }
        System.out.println("Done.");
    }

    public static void main(String args[]) {
        String fileList[] = {"E:\\JavaApplication14\\src\\javaapplication14\\issues.pdf", "E:\\JavaApplication14\\src\\javaapplication14\\newTextDocument.txt"};
        if (fileList.length != 2) {
            System.out.println("Usage: java PDFTextParser <InputPDFFilename> <OutputTextFile>");
            System.exit(1);
        }
        JavaApplication14 pdfTextParserObj = new JavaApplication14();
        String pdfToText = pdfTextParserObj.pdftoText(fileList[0]);
        if (pdfToText == null) {
            System.out.println("PDF to Text Conversion failed.");
        } else {
            System.out.println("\nThe text parsed from the PDF Document....\n" + pdfToText);
            pdfTextParserObj.writeTexttoFile(pdfToText, fileList[1]);
        }
    }
}
于 2016-02-29T10:53:02.920 回答