当前位置: 首页 > 知识库问答 >
问题:

为什么pdf只包含一个字段约500KB

谭景福
2023-03-14

在这里你可以下载一个acroform字段的pdf,他的大小正好是427KB

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

共有1个答案

郗奇玮
2023-03-14

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大小。

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

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());
    }
}
vtField.setValue("Ayşe");
 类似资料:
  • 问题内容: 在这里,您可以下载 一个acroform字段的pdf,其大小恰好是427Kb 如果我删除此唯一字段,则文件仅为3Kb,请为什么会发生这种情况?我尝试使用PDF Debugger进行分析,但似乎没有任何异常。 问题答案: 在acroform默认资源中有一个嵌入的“ Arial”字体,请参见Root/AcroForm/DR/Font/Arial/FontDescriptor/FontFil

  • 为什么在那里插入? 如果没有一个好的理由:我能用什么方法摆脱它吗? 如果您想使用以下示例:https://godbolt.org/z/74ycy63se

  • 问题内容: 从golang规范 是否有使用内的 空白 字段的实际方案?(一些代码片段将不胜感激) 问题答案: 填充正是所谓的:一些填充,用于将以下字段与您的需求对齐,例如,匹配C结构的布局。无法访问它(至少在没有软件包不安全的情况下)。

  • 创建一个同步多线程系统,以确定三个文本文件中所有整数或分数的总数。如果流被阻塞,则必须将其名称显示为"LOCKED"。为什么只计算一个文件(带锁的线程)?程序显示的内容:Thread-0 Locked!线程-2锁定!123.321 322099只有一个文件

  • 我的webpack加载器如下所示: 但尝试包含文件时出错 ./node_modules/css-loader中出错?{“sourceMap”:true,“modules”:true,“importloaders”:1,“localidentname”:“[local]_[hash:base64:3]”}!./node_modules/postcss-loader/lib?{“plugins”:[n

  • 问题内容: 在过去的几周里,我一直在使用AngularJS,而真正困扰我的一件事是,即使尝试了所有置换或http://docs.angularjs.org/api/ng规范中定义的配置,.directive:select,我仍然得到一个空选项作为select元素的第一个子元素。 这是玉: 这里的控制器: 最后,这是生成的HTML: 我需要怎么做才能摆脱它? PS:事情也不需要这样做,但是如果您使用