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

时间:2015-07-01 12:19:04

标签: 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);

1 个答案:

答案 0 :(得分:1)

请允许我接受您的代码并介绍一些伪代码,以告诉您如何执行此操作:

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);
}

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

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