我们使用 itext5 库来填充 PDF 数据。生成的 PDF 不符合 AODA。如果我保存生成的 PDF 并尝试用 Adobe Reader 大声朗读它,它只会在这里和那里读几个字。现在有人在这个问题的 itext 解决方案。我们正在使用 itext 中的 PDFStamper 和 PDFCopy 类。这是一段代码:

public PDFPopulator(byte[] pdfTemplate, ReportOptions options, OutputStream resultPdf) throws Exception {
        originalPdfTemplate = pdfTemplate;
        PdfReader reader = new PdfReader(pdfTemplate);
        reader.consolidateNamedDestinations();
        pdfTemplate = applyOptions(pdfTemplate, options);
        document = new Document(reader.getPageSizeWithRotation(1));
        // If we used PdfSmartCopy the result PDF would be significantly smaller (15Mb VS 260Mb),
        // but the memory consumption would be slightly bigger (10-15 times) and the execution time longer (5%). 
        // Personally, I would use PdfSmartCopy over PdfCopy and have a smaller PDF, especially as we going 
        // to put the report generation in a queue.
        writer = new PdfSmartCopy(document, resultPdf);
        writer.setFullCompression();
        writer.setPdfVersion(PdfWriter.VERSION_1_7);
        writer.setCloseStream(false);
        document.open();

        this.pdfTemplate = pdfTemplate;
    }

public void populate(List<FieldContainer> fieldContainers) throws Exception {
        long timestamp = System.currentTimeMillis();
        for (FieldContainer fContainer : fieldContainers) {
            byte[] pdfTemplateTemp = fContainer.getOptions() != null 
                    ? applyOptions(originalPdfTemplate, fContainer.getOptions()) 
                    : pdfTemplate;
            PdfReader reader = new PdfReader(pdfTemplateTemp);
            reader.consolidateNamedDestinations();
            int numPages = reader.getNumberOfPages();
            reportCounter++;

            // Fill the form
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PdfStamper stamp = new PdfStamper(reader, baos);
            AcroFields form = stamp.getAcroFields();

            for (String fieldName : form.getFields().keySet()) {
                Object fieldValue = fContainer.getValue(fieldName);
                if (fieldValue != null && !fieldValue.equals("")) {
                    if (fieldName.startsWith("getImage")) {
                        addImage(stamp, form.getFieldItem(fieldName), fieldValue);
                    } else {
                        form.setField(fieldName, fieldValue.toString());
                    }
                }
            }
            stamp.setFormFlattening(true);
            stamp.close();

            // Write pages
            PdfReader tempRead = new PdfReader(baos.toByteArray());
            for (int i = 1; i <= numPages; i++) {
                writer.addPage(writer.getImportedPage(tempRead, i));
            }
            writer.freeReader(tempRead);
            writer.freeReader(reader);
            writer.flush();
            baos.close();
            tempRead.close();
            reader.close();
        }
        if(LOGGER.isLoggable(Level.FINE)){
            LOGGER.fine("PDF populated in : " + ((System.currentTimeMillis() - timestamp) / 1000) + " sec.");
        }
    }