itextpdf / PdfContentByte / Font – 如何组合2个或更多的加粗、斜体和下划线

huangapple go评论114阅读模式
英文:

itextpdf / PdfContentByte / Font - How to combine 2 or more of BOLD, ITALICS AND UNDERLINE

问题

作为我正在进行的项目的一部分,我需要使用数据库中的内容、位置和文本样式创建PDF文件。我正在使用PdfContentByte来向文档添加文本。内容、位置和文本大小都能正常工作,但我不知道如何将粗体、斜体和下划线等文本样式组合到一起。我查看了许多在SOF上的其他问题,但是无法使其工作。

我尝试过的方法是使用数据库中的文本样式创建一个Font,然后像下面这样使用Font.getBaseFont()来获取一个BaseFont

Font custFont = FontFactory.getFont("/fonts/arial.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 0.8f, Font.BOLDITALIC, BaseColor.BLACK);
BaseFont baseFont = custFont.getBaseFont();
pdfContentByte.setFontAndSize(baseFont, fontSizeFromDB);
pdfContentByte.showTextAligned(Element.ALIGN_LEFT, "Text From DB", xPosFromDB, yPosFromDB, 0);

但是这并不起作用。只有字体族被复制到baseFont对象中。

然而,当我像下面这样在段落中使用该字体时,字体样式就能正常工作。(但我不能使用这个,因为我需要将内容插入到特定的位置,为此我需要使用PdfContentByte

Font custFontTimes = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD | Font.UNDERLINE);
Paragraph paragraphCusTime = new Paragraph("Paragraph text in custFontTimes", custFontTimes);
document.add(paragraphCusTime);
英文:

As a part of the project I am working on, I need to create PDF files using the contents, position, text style from database. I am using PdfContentByte to add text to the document. Contents, position and text size work fine, but I am not able to understand how to incorporate text style that could be combination of one or more from Bold, Italics, and Underline. I have looked at many other questions on SOF, but not able to get it working.
What I have tried to do is create a Font using the text style from database and then get a BaseFont using Font.getBaseFont() as shown below.

Font custFont = FontFactory.getFont("/fonts/arial.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 0.8f, Font.BOLDITALIC, BaseColor.BLACK); 
// "/fonts/arial.ttf", Font.BOLDITALIC, BaseColor.BLACK ETC BASED ON THE FONT STYLE FROM DB
BaseFont baseFont = custFont.getBaseFont();
pdfContentByte.setFontAndSize(baseFont, fontSizeFromDB);
pdfContentByte.showTextAligned(Element.ALIGN_LEFT, "Text From DB", xPosFromDB, yPosFromDB, 0);

This does not work. Only the Font family is copied into baseFont object.

However, when I use the Font in a paragraph like below font styles are working fine. (But I cannot use this as I need to insert the contents in a specific position for which I need to use PdfContentByte )

Font custFontTimes = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD | Font.UNDERLINE);  
Paragraph paragraphCusTime = new Paragraph("Paragraph text in custFontTimes", custFontTimes);
document.add(paragraphCusTime);

答案1

得分: 1

你可以通过创建带有组合的 BoldItalic 样式修饰符的基础字体来实现这一点。使用 pdfContentByte.setFontAndSize 的限制在于你只能使用其中一个14种内置类型之一,而 TIMES_BOLDITALIC 是唯一符合你条件的类型。

看起来你正在使用的是 iText 2.1.7,我没有它的副本来测试是否可行,但是使用内置字体的简单解决方案可能如下所示:

BaseFont baseFont = BaseFont.createFont(BaseFont.TIMES_BOLDITALIC, BaseFont.CP1257, BaseFont.EMBEDDED);

或者你可以尝试使用带有样式修饰符的 TrueType 字体。你需要尝试不同的字体来找到既有粗体又有斜体的字体,但当你找到一个时,代码可能类似于:

BaseFont baseFont = BaseFont.createFont("Arial-CE-Bold-Italic", BaseFont.CP1257, BaseFont.EMBEDDED);

请注意,嵌入的字体可能会表现不正常,你可能需要尝试将嵌入设置为 false。

我已经很久没有使用过 iText 2.1.7 了,但它确实有许多类似这样的限制,我强烈建议你从现在开始使用最新版本的 iText,特别是考虑到很难找到旧版本的示例。

API 参考:
https://coderanch.com/how-to/javadoc/itext-2.1.7/com/lowagie/text/pdf/BaseFont.html#createFont(java.lang.String,%20java.lang.String,%20boolean)

API 引用:

BaseFont createFont(java.lang.String name,
java.lang.String encoding,
boolean embedded,
boolean forceRead)
throws DocumentException,
java.io.IOException

创建一个新字体。这个字体可以是 14 种内置类型之一,也可以是由 AFM 或 PFM 文件引用的 Type1 字体,TrueType 字体(简单或集合)或来自 Adobe 亚洲字体包的 CJK 字体。TrueType 字体和 CJK 字体可以在名称后附加可选的样式修饰符。这些修饰符包括:Bold、Italic 和 BoldItalic。例如,“STSong-Light,Bold”。

英文:

You could do this by creating a base font with the combined BoldItalic style modifier. The limitation of using pdfContentByte.setFontAndSize is that you can only use one of the 14 built in types, and TIMES_BOLDITALIC is the only one that fits your criteria.

It seems like you are using iText 2.1.7 which I don't have a copy of to test if it works, but a simple solution using the built in font might look something like this:

BaseFont baseFont = BaseFont.createFont(BaseFont.TIMES_BOLDITALIC, BaseFont.CP1257, BaseFont.EMBEDDED);

Or you could try your hand at using a TrueType font with a style modifier. You would need to play with this to find a font that has both bold and italic, but when you find one it may look something like this:

BaseFont baseFont = BaseFont.createFont("Arial-CE-Bold-Italic", BaseFont.CP1257, BaseFont.EMBEDDED);

Note that embedded fonts may misbehave, you may need to play around with embedded set to false.

It's been a long time since I used iText 2.1.7, but it does come with a number of limitations like this, I strongly recommend using the latest version of iText going forward, especially given how hard it is to find examples for the older version.

API reference:
https://coderanch.com/how-to/javadoc/itext-2.1.7/com/lowagie/text/pdf/BaseFont.html#createFont(java.lang.String,%20java.lang.String,%20boolean)

API quote:

> BaseFont createFont(java.lang.String name,
java.lang.String encoding,
boolean embedded,
boolean forceRead)
throws DocumentException,
java.io.IOException
>
> Creates a new font. This font can be one of the 14 built in types, a
> Type1 font referred to by an AFM or PFM file, a TrueType font (simple
> or collection) or a CJK font from the Adobe Asian Font Pack. TrueType
> fonts and CJK fonts can have an optional style modifier appended to
> the name. These modifiers are: Bold, Italic and BoldItalic. An example
> would be "STSong-Light,Bold".

huangapple
  • 本文由 发表于 2020年10月20日 07:25:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/64436367.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定