【问题标题】:Using pdfbox - how to get the font from a COSName?使用 pdfbox - 如何从 COSName 中获取字体?
【发布时间】:2018-03-23 05:41:39
【问题描述】:

如何从 COSName 中获取字体?

我正在寻找的解决方案看起来像这样:

COSDictionary dict = new COSDictionary();
dict.add(fontname, something); // fontname COSName from below code
PDFontFactory.createFont(dict);

如果您需要更多背景知识,我在下面添加了整个故事:

我尝试替换 pdf 中的一些字符串。这会成功(只要所有文本都存储在一个令牌中)。为了保持格式,我喜欢将文本重新居中。据我了解,我可以通过获取旧字符串和新字符串的宽度来做到这一点,进行一些简单的计算并设置新位置。

我在 stackoverflow 上找到了替换 https://stackoverflow.com/a/36404377 的一些灵感(是的,它有一些问题,但适用于我的简单 pdf 文件。还有 How to center a text using PDFBox。不幸的是,这个示例使用了字体常量。

因此,使用第一个链接的代码,我得到了运算符“TJ”和“Tj”的处理。

  PDFStreamParser parser = new PDFStreamParser(page);
  parser.parse();
  java.util.List<Object> tokens = parser.getTokens();
  for (int j = 0; j < tokens.size(); j++)
  {
    Object next = tokens.get(j);
    if (next instanceof Operator)
    {
      Operator op = (Operator) next;
      // Tj and TJ are the two operators that display strings in a PDF
      if (op.getName().equals("Tj"))
      {
        // Tj takes one operator and that is the string to display so lets
        // update that operator
        COSString previous = (COSString) tokens.get(j - 1);
        String string = previous.getString();
        String replaced = prh.getReplacement(string);
        if (!string.equals(replaced))
        { // if changes are there, replace the content
          previous.setValue(replaced.getBytes());
          float xpos = getPosX(tokens, j);
          //if (true) // center the text
          if (6 * xpos > page.getMediaBox().getWidth()) // check if text starts right from 1/xth page width
          {
            float fontsize = getFontSize(tokens, j);
            COSName fontname = getFontName(tokens, j);
            // TODO
            PDFont font = ?getFont?(fontname);
            // TODO
            float widthnew = getStringWidth(replaced, font, fontsize);
            setPosX(tokens, j, page.getMediaBox().getWidth() / 2F - (widthnew / 2F));
          }
          replaceCount++;
        }
      }

考虑到TODO标签之间的代码,我会从token列表中获取需要的值。 (是的,这段代码很糟糕,但现在让我专注于主要问题)

有了字符串、大小和字体,我应该能够从示例代码中调用 getWidth(..) 方法。

不幸的是,我在从 COSName 变量创建字体时遇到了麻烦。

PDFont 不提供按名称创建字体的方法。 PDFontFactory 看起来不错,但需要一个 COSDictionary。这是我放弃并请求您帮助的一点。

【问题讨论】:

    标签: pdfbox


    【解决方案1】:

    名称与页面资源中的字体对象相关联。

    假设您使用 PDFBox 2.0.x 并且 pagePDPage 实例,您可以使用以下方法解析名称 fontname

    PDFont font = page.getResources().getFont(fontname);
    

    但是 cmets 对您引用的问题的警告仍然存在:这种方法仅适用于非常简单的 PDF,甚至可能损坏其他 PDF。

    【讨论】:

      【解决方案2】:
      try {
          //Loading an existing document 
          File file = new File("UKRSICH_Mo6i-Spikyer_z1560-FAV.pdf");
          PDDocument document = PDDocument.load(file);
      
          PDPage page = document.getPage(0);
          PDResources pageResources = page.getResources();
      
                  System.out.println(pageResources.getFontNames() );
      
          for (COSName key : pageResources.getFontNames())
          {
          PDFont font = pageResources.getFont(key);
      
                  System.out.println("Font: " + font.getName());
          }
      
      
          document.close();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-18
        • 2016-11-17
        • 2014-03-09
        • 1970-01-01
        • 2016-11-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多