gpt4 book ai didi

java - 为什么pdf只包含一个字段大约500Kb

转载 作者:行者123 更新时间:2023-12-02 01:34:11 26 4
gpt4 key购买 nike

在这里您可以download pdf具有一个 acroform 字段,其大小恰好为 427Kb

如果我删除这个唯一字段,文件只有 3Kb,为什么会发生这种情况?我尝试使用 PDF 调试器进行分析,对我来说没有什么奇怪的。

enter image description here

最佳答案

acroform 默认资源中有嵌入的“Arial”字体,请参阅 Root/AcroForm/DR/Font/Arial/FontDescriptor/FontFile2

您或创建该 pdf 的人无缘无故地添加了它。未使用/引用该字体。对于 acroform 默认资源,您可以检查每个字段的/DA 条目(默认外观)是否包含字体名称。

当您以某种方式删除该字段时,您也从 acroForm 默认资源中删除了字体。 (你没有写如何删除它)

这里有一些代码可以做到这一点(空检查大多缺失):

    PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
PDResources defaultResources = acroForm.getDefaultResources();
COSDictionary fontDict = (COSDictionary) defaultResources.getCOSObject().getDictionaryObject(COSName.FONT);
List<String> defaultAppearances = new ArrayList<>();
List<COSName> fontDeletionList = new ArrayList<>();
for (PDField field : acroForm.getFieldTree())
{
if (field instanceof PDVariableText)
{
PDVariableText vtField = (PDVariableText) field;
defaultAppearances.add(vtField.getDefaultAppearance());
}
}
for (COSName fontName : defaultResources.getFontNames())
{
if (COSName.HELV.equals(fontName) || COSName.ZA_DB.equals(fontName))
{
// Adobe default, always keep
continue;
}
boolean found = false;
for (String da : defaultAppearances)
{
if (da != null && da.contains("/" + fontName.getName()))
{
found = true;
break;
}
}
System.out.println(fontName + ": " + found);
if (!found)
{
fontDeletionList.add(fontName);
}
}
System.out.println("deletion list: " + fontDeletionList);
for (COSName fontName : fontDeletionList)
{
fontDict.removeItem(fontName);
}

生成的文件现在大小为 5KB。

我没有检查注释。其中一些还具有/DA 字符串,但尚不清楚在重建丢失的外观流时是否使用 acroform 默认资源字体。

更新:下面是一些用 Helv 替换 Arial 的附加代码:

for (PDField field : acroForm.getFieldTree())
{
if (field instanceof PDVariableText)
{
PDVariableText vtField = (PDVariableText) field;
String defaultAppearance = vtField.getDefaultAppearance();
if (defaultAppearance.startsWith("/Arial"))
{
vtField.setDefaultAppearance("/Helv " + defaultAppearance.substring(7));
vtField.getWidgets().get(0).setAppearance(null); // this removes the font usage
vtField.setValue(vtField.getValueAsString());
}
defaultAppearances.add(vtField.getDefaultAppearance());
}
}

请注意,这可能不是一个好主意,因为标准 14 种字体只有有限的字符。尝试一下

vtField.setValue("Ayşe");

你会得到一个异常(exception)。

更通用的替换字体的代码可以在 this answer 中找到。 .

关于java - 为什么pdf只包含一个字段大约500Kb,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55490141/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com