java - iText - 检查附件是否存在/多次链接附件

标签 java itext

有没有办法在创建文档时(而不是在将文档保存到磁盘后)检查 PDF 文档中是否已存在附件?在将 XML 解析为 PDF 时,我遇到了多个具有相同内容(来自 XML > byte[] 的 Base64 字符串)和相同名称的附件。目前附件已添加多次,但我想检查附件(具有相同内容或名称)是否已存在(PdfWriter API?),如果是,则只应为现有附件创建一个新的注释。

注意:检查应该在创建 PDF 时进行,而不是使用 PdfReader 和现有 PDF 进行

编辑: 感谢@Bruno Lowagie,我让它工作了:

protected HashMap<String, PdfFileSpecification> cache = new HashMap<>();
private final byte[] BUFFER = new byte[1024];

public PdfFileSpecification getPdfFileSpecification(final PdfWriter pdfWriter, final String name, final byte[] data) throws IOException {

    String hash = createMD5Hash(data);
    PdfFileSpecification pdfFileSpecification = cache.get(hash);

    if (pdfFileSpecification == null) {
        pdfFileSpecification = PdfFileSpecification.fileEmbedded(pdfWriter, null, name, data);
        cache.put(hash, pdfFileSpecification);
        return pdfFileSpecification;
    }
    System.out.println(String.format("Name: %s Hash: %s", name, hash));
    return pdfFileSpecification;
}

private String createMD5Hash(final byte[] data) {

MessageDigest messageDigest;

    try {
        messageDigest = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
        return null;
    }

    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);

    try {
        int i;
        while ((i = byteArrayInputStream.read(BUFFER)) != -1) {
            messageDigest.update(BUFFER, 0, i);
        }
        byteArrayInputStream.close();
    } catch (IOException e) {
        return null;
    }
    byte[] mdbytes = messageDigest.digest();

    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < mdbytes.length; i++) {
        sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
    }

    return sb.toString();
}

所以每次我必须处理新的附件时,我都会这样做:

PdfFileSpecification fs = getPdfFileSpecification(pdfWriter, name, data)
PdfAnnotation an = PdfAnnotation.createFileAttachment(pdfWriter, rectangle, name, fs);

最佳答案

请允许我使用您的代码并引入一些伪代码来向您展示我将如何执行此操作:

protected Map<String, PdfFileSpecification> cache =
    new HashMap<String, PdfFileSpecification>();

public void cellLayout(final PdfPCell pdfPCell, final Rectangle rectangle, final PdfContentByte[] pdfContentBytes) {
    String hasheddata = createHash(attachment);
    PdfFileSpecification fs = cache.get(hasheddata);
    if (fs == null) {
        fs = PdfFileSpecification.fileEmbedded(writer, null, displayname, attachment);
        cache.put(hasheddata, fs);
    }
    PdfAnnotation an = PdfAnnotation.createFileAttachment(writer, rectangle, displayname, fs);
    writer.addAnnotation(an);
}

这段代码无法编译,因为我遗漏了一些与问题无关的部分。我只保留了解释为文件规范创建缓存概念的内容。

我创建了附件字节的哈希值以节省内存。您必须使用您选择的哈希算法来实现 createHash() 方法。在创建将字节写入 PdfWriter 的新 FileSpecification 之前,我会检查是否无法重用现有的文件规范。如果存在,我会在注释中重用它。如果它不存在,我将创建一个新的文件规范。

关于java - iText - 检查附件是否存在/多次链接附件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31161115/

相关文章:

java - itext pdf,如何将字符串绘制到特定位置?

c# - iTextSharp .NET PDF - 无法更改 PDF Producer

java - NoClassDefFound错误: com/itextpdf/text/DocumentException when exporting jasper to pdf

Java:同步操作与波动性究竟有何关系?

java - XHTML 到 PDF 使用 Flying Saucer 如何缓存 css

java - 是否有构建 64 位 JD2XX DLL 的简单方法?

java - 如何使用 Java 存储过程显示表数据?

java - 使用 iText 打开 PDF 时自动打开打印对话框

bluetooth - 如何使用蓝牙发送文件到手机?

java - 阅读有关蓝牙的 Android 开发人员?