itext:在单词中加粗单个字母

时间:2014-11-22 17:53:13

标签: java itext

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

考虑这句话,“这是一个词”。我可以把那句话大胆的所有“我”吗?所以输出将是这样的: “ s 是一个词”

所以为了得到第一个单词(这个),我真的必须为一个单词创建三个块而不是将所有块一起添加吗?或者还有另一种方法吗?

有三个块我的意思是这样的(我知道它不是工作代码,但为了便于阅读而使它像这样:)

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不同,因为它没有char。我希望你们明白我的意思,我将在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;
    }

2 个答案:

答案 0 :(得分:2)

为什么你说代码示例不起作用?我已将您的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

enter image description here

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

根据评论中的其他问题进行更新

  

我可以将颜色指定为HEX。例如像BaseColor(#ffcd03);之类的东西我理解你可以像new BaseColor(0, 0, 255)那样指定它,但是HEX会更有用。

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

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

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字符串(()之间或<>之间),并引入Tf和{ {1}}运营商。

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

答案 1 :(得分:1)

如果有人以粗体显示少数几个单词而且很少正常,那么就这样做,

NAME :Ullas

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