PDFBox 2.0.9中PDAnnotationTextMarkup字体大小及颜色修改求助
我明白你在PDFBox 2.0.9里折腾PDAnnotationTextMarkup的字体大小和颜色时遇到的坎儿了——这俩属性的设置确实不像普通文本那样直白,得找对路子才行。我给你两个实用的示例,分别对应弹出批注文本和页面外观文本的样式修改:
示例1:修改弹出批注窗口的文本样式(字体大小+颜色)
如果是想改批注弹出窗口里的文本样式,setRichContent是正确方向,但需要用符合规范的XHTML富文本格式。下面是完整代码:
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup; import org.apache.pdfbox.pdmodel.interactive.annotation.PDRichContent; import java.io.IOException; public class PopupAnnotationStyle { public static void main(String[] args) throws IOException { try (PDDocument doc = new PDDocument()) { PDPage page = new PDPage(); doc.addPage(page); // 创建高亮类型的文本批注 PDAnnotationTextMarkup highlight = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT); // 设置批注在页面上的位置和区域 highlight.setRectangle(new PDRectangle(50, 700, 200, 20)); highlight.setQuadPoints(new float[]{50,720, 250,720, 50,700, 250,700}); // 构造带样式的富文本内容 String richContent = "<body xmlns=\"http://www.w3.org/1999/xhtml\">" + "<p style=\"font-size:14pt; color:#FF0000; font-family:Arial;\">" + "这是设置了14pt字号、红色字体的批注内容" + "</p>" + "</body>"; PDRichContent pdRichContent = new PDRichContent(); pdRichContent.setContent(richContent); highlight.setRichContent(pdRichContent); // 设置普通文本作为降级方案(兼容不支持富文本的阅读器) highlight.setContents("这是设置了14pt字号、红色字体的批注内容"); // 将批注添加到页面 page.getAnnotations().add(highlight); doc.save("highlight_popup_style.pdf"); } } }
关键说明:
- 富文本必须包含
xmlns命名空间,否则部分阅读器可能无法识别样式 - 同时设置
setContents是为了兼容老旧阅读器,确保内容能正常显示 - 可以通过CSS样式直接指定字体、字号、颜色等属性
示例2:修改页面上批注的外观文本样式
如果是想修改页面上直接显示的批注文本(比如下划线批注旁的说明文字),就需要手动构建PDAppearanceStream,替换默认的外观生成逻辑:
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDResources; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream; import org.apache.pdfbox.pdmodel.graphics.color.PDColor; import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB; import java.io.IOException; public class AnnotationAppearanceStyle { public static void main(String[] args) throws IOException { try (PDDocument doc = new PDDocument()) { PDPage page = new PDPage(); doc.addPage(page); // 创建下划线类型的文本批注 PDAnnotationTextMarkup underline = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_UNDERLINE); underline.setRectangle(new PDRectangle(50, 700, 220, 30)); underline.setQuadPoints(new float[]{50,710, 250,710, 50,700, 250,700}); // 构建自定义外观字典 PDAppearanceDictionary appearance = new PDAppearanceDictionary(); PDAppearanceStream appearanceStream = new PDAppearanceStream(doc); // 设置外观流的边界框 appearanceStream.setBBox(new PDRectangle(0, 0, 220, 30)); // 配置资源:加载Helvetica字体 PDResources resources = new PDResources(); resources.putFont("CustomFont", PDType1Font.HELVETICA_BOLD); appearanceStream.setResources(resources); // 编写PDF内容流指令,定义文本样式和绘制逻辑 StringBuilder content = new StringBuilder(); content.append("/CustomFont 12 Tf\n"); // 设置字体和字号 content.append(new PDColor(new float[]{0, 0, 1}, PDDeviceRGB.INSTANCE).toPDFString()).append(" RG\n"); // 设置文本为蓝色 content.append("25 8 Td\n"); // 调整文本绘制位置 content.append("(页面上的自定义批注文本) Tj\n"); // 绘制文本 // 绘制下划线(匹配批注类型) content.append("0 0 m\n"); content.append("200 0 l\n"); content.append("S\n"); appearanceStream.setContents(content.toString()); appearance.setNormalAppearance(appearanceStream); underline.setAppearance(appearance); page.getAnnotations().add(underline); doc.save("underline_appearance_style.pdf"); } } }
关键说明:
- 外观流的坐标系是基于批注自身的矩形区域,所以文本位置需要相对这个区域调整
- PDF内容流指令需要遵循PDF语法规范,比如
Tf用于设置字体,RG设置颜色,Td移动文本光标,Tj绘制文本 - 可以加载自定义字体,但需要确保字体文件被正确嵌入到PDF中
内容的提问来源于stack exchange,提问作者mdc
相关产品推荐
相关产品推荐

