【问题标题】:itext: make a single letter bold within a worditext:将单词中的单个字母加粗
【发布时间】:2014-11-22 17:53:13
【问题描述】:

是否可以将 itext 中某个单词中的特定字母加粗?

考虑这句话,“这是一个词”。我可以把这句话的所有“我”都加粗吗?所以输出会是这样的: "this is a word"

所以,为了让第一个词正确(这个),我真的必须为一个词创建三个块,然后将所有块加在一起吗?还是有其他方法?

三个块我的意思是这样的(我知道它的代码不起作用,但为了可读性而这样做):

Chunk chunk1 = new Chunk("th");
Chunk chunk2 = new Chunk("i", bold);
Chunk chunk3 = new Chunk("s");

Paragraph p = new Paragraph(); 
p.add(chunk1); p.add(chunk2); p.add(chunk3)

必须有更好的方法。一些“字符串”我也想着色,比如字符串中的每个字母都有不同的颜色,我是否必须为每个字母创建块而不是组合它们?

使用 android 中的 EditText 框来更改每个字母的颜色,我可以使用 SpannableString。但它与 itext 不同,因为它没有字符。我希望你们明白我的意思,我将在一个editText框中发布两种关于我如何在android中解决的方法。现在我只想要一种类似的方法来将彩色和粗体文本写入 pdf。

    public SpannableString colorizeText(String text) {
        SpannableString spannableColor = new SpannableString(text);
        int x = 1;
        for(char letter : text.toCharArray()){
            spannableColor.setSpan(new ForegroundColorSpan(returnCorrectColor(letter)), x-1, x, 0);
            x++;
        }
        return spannableColor;
    }

    private int returnCorrectColor(char letter) {
        String theLetter = Character.toString(letter);
        if (theLetter.contains("a")){
            return Color.BLUE;
        }
        else if(theLetter.contains("o")){
            return Color.GREEN;
        }
        return Color.RED;
    }

【问题讨论】:

    标签: java itext


    【解决方案1】:

    为什么你说你的代码示例不起作用?我已将您的 iText 和 Android 示例合并为一个新示例:ColoredLetters

    我写了一个和你类似的方法:

    private Chunk returnCorrectColor(char letter) {
        if (letter == 'b'){
            return B;
        }
        else if(letter == 'g'){
            return G;
        }
        return new Chunk(String.valueOf(letter), RED_NORMAL);
    }
    

    请注意,我使用了一些常量:

    public static final Font RED_NORMAL = new Font(FontFamily.HELVETICA, 12, Font.NORMAL, BaseColor.RED);
    public static final Font BLUE_BOLD = new Font(FontFamily.HELVETICA, 12, Font.BOLD, BaseColor.BLUE);
    public static final Font GREEN_ITALIC = new Font(FontFamily.HELVETICA, 12, Font.ITALIC, BaseColor.GREEN);
    public static final Chunk B = new Chunk("b", BLUE_BOLD);
    public static final Chunk G = new Chunk("g", GREEN_ITALIC);
    

    现在我可以像这样构造一个Paragraph

    Paragraph p = new Paragraph();
    String s = "all text is written in red, except the letters b and g; they are written in blue and green.";
    for (int i = 0; i < s.length(); i++) {
        p.add(returnCorrectColor(s.charAt(i)));
    }
    

    结果如下所示:colored_letters.pdf

    另一种方法是使用不同的字体,其中 fontB 仅包含字母 b,而 fontG 仅包含字母 g。然后,您可以将这些字体与普通字体一起声明给FontSelector 对象。然后,您可以处理字体。有关使用此替代方法的示例,请阅读我对以下问题的回答:iText changing the font color and size when using fontselector

    基于 cmets 中的其他问题的更新

    我可以将颜色指定为十六进制吗?例如像BaseColor(#ffcd03); 这样的东西我知道你可以像new BaseColor(0, 0, 255) 这样指定它,但是HEX 会更有用。

    实际上,我自己更喜欢 HEX 表示法,因为当它们以 HEX 表示法表示时,我更容易识别某些颜色。这就是为什么我经常在 Java 中使用 HEX 表示法来表示整数:new BaseColor(0xFF, 0xCD, 0x03);

    另外,HtmlUtilities 类中有一个decodeColor() 方法可以这样使用:

    BaseColor color = HtmlUtilities.decodeColor("#ffcd03");
    

    有没有办法只定义颜色并将字体保留为默认值。像这样: public static final Font RED_NORMAL = new Font(BaseColor.RED);

    你可以这样创建字体:

    new Font(FontFamily.UNDEFINED, 12, Font.UNDEFINED, BaseColor.RED);
    

    现在,当您将具有此类字体的 Chunk 添加到 Paragraph 时,它应该采用在 Paragraph 级别定义的字体(这就是我第一次编写 iText 时的意图。我应该检查一下如果这仍然是真的)。​​

    我的目标是编写一个程序,在不改变 PDF 结构的情况下为现有 PDF 文件着色。您认为这种方法是否适用于此目的(性能等)?

    不,这不起作用。如果您阅读了chapter 6 of the second edition of iText in Action 的介绍,您就会明白 PDF 不是为编辑而创建的格式。屏幕截图中显示的句子的内部语法如下所示:

    BT
    36 806 Td
    0 -16 Td
    /F1 12 Tf
    1 0 0 rg
    (all text is written in red, except the letters ) Tj
    0 g
    /F2 12 Tf
    0 0 1 rg
    (b) Tj
    0 g
    /F1 12 Tf
    1 0 0 rg
    ( and ) Tj
    0 g
    /F3 12 Tf
    0 1 0 rg
    (g) Tj
    0 g
    /F1 12 Tf
    1 0 0 rg
    (; they are written in ) Tj
    0 g
    /F2 12 Tf
    0 0 1 rg
    (b) Tj
    0 g
    /F1 12 Tf
    1 0 0 rg
    (lue and ) Tj
    0 g
    /F3 12 Tf
    0 1 0 rg
    (g) Tj
    0 g
    /F1 12 Tf
    1 0 0 rg
    (reen.) Tj
    0 g
    0 0 Td
    ET
    

    如你所见,Tf 操作符改变了字体:

    • /F1 是常规字体,
    • /F2 是粗体,
    • /F3 是斜体。

    这些名称引用页面的/Resources 字典中的字体,您可以在其中找到对实际字体描述符的引用。

    rg 运算符更改颜色。当我们使用红色、绿色和蓝色时,您可以识别操作数 1 0 00 1 00 0 1

    这看起来相当简单,因为我们使用了 WINANSI 编码。可以解析内容流,查找所有 PDF 字符串(在() 之间或&lt;&gt; 之间),并引入Tfrg 运算符。

    但是:内容流并不总是像这里那样微不足道。可以使用自定义编码,可以使用 Unicode,... 看看我对以下问题的回答中的第二个屏幕截图:Can't get Czech characters while generating a PDF。您将了解更改现有 PDF 中颜色的计划并非易事。我们过去曾为我们的一位客户做过这样的项目。这是一个耗时数周的项目。

    【讨论】:

    • 由布鲁诺本人回答,我感到很荣幸:)。一整天都在看你的书,在 youtube 上看你。我写道它不起作用,因为我没有定义字体“粗体”。你完全理解我的意思,它适用于我的项目。我的目标是编写一个程序,在不改变 PDF 结构的情况下为现有 PDF 文件着色。您认为这种方法是否适用于此目的(性能等)?我想给每一个字母上色。太好了,您使用了常量,我想这将提高性能,而不必在循环中实例化字体。
    • 哦,有没有办法只定义颜色并将字体保留为默认值。像这样: public static final Font RED_NORMAL = new Font(BaseColor.RED);
    • 当我在做的时候,呵呵。我可以将颜色指定为十六进制吗?例如像 BaseColor(#ffcd03);我知道您可以像 new BaseColor(0, 0, 255) 一样指定它,但是 HEX 会更有用。
    • 感谢您的详尽回答,以及如何使用 HEX 和 UNDEFINED 的技巧。 “不,这不行……” 太糟糕了,我想我知道虽然我不想接受它。但是你也提到你已经做到了,这意味着至少不是不可能的。现在我的应用程序可以接收 PDF,提取文本,对其进行着色,而不是从该彩色文本创建 pdf。所以现在我的下一步是编写一个在提取的文本中查找标题/标题的方法,呵呵。感谢您警告我此过程可能需要一段时间,但无论如何都无法实现。
    • 观看m.youtube.com/watch?v=lZnbhnU4m3Y 了解我们所做项目的一些信息。 sourceforge 上的 SVN 存储库中提供了一些示例代码。在主干下的沙箱中查找 java one 示例。 (我正在用手机接听。我现在要找到正确的链接不太实际。)
    【解决方案2】:

    如果有人在寻找几个粗体字和几个正常字,那么你就是这样做的,

    姓名:乌拉斯

      Paragraph NameField = new Paragraph(); 
            NameField.add(new Chunk("   NAME : ", new Font(base, 11f, Font.BOLD)));
            NameField.add(new Chunk("   Ullas Kularni", new Font(base, 11f, Font.NORMAL)));
            NameField.setAlignment(Element.ALIGN_CENTER);
            doc.add(NameField);
    

    【讨论】:

      猜你喜欢
      • 2020-12-08
      • 2020-11-02
      • 1970-01-01
      • 2012-04-30
      • 2015-08-17
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      相关资源
      最近更新 更多