如何在iText生成的PDF中为Java关键字添加颜色?
解决Java文件转PDF时关键字着色问题
你的问题核心在于ANSI颜色转义码是终端输出专用编码,iText无法识别,必须改用iText原生的文本样式控制方式——通过Chunk对象分别定义普通文本和关键字的显示样式。
实现思路
- 摒弃ANSI标记方案,直接在PDF生成流程中处理文本:将原Java代码拆分为普通文本片段和关键字片段。
- 为关键字片段单独设置指定颜色的
Font,普通文本使用默认字体,再将这些Chunk依次拼接成段落写入PDF。
完整代码实现
import com.itextpdf.text.*; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfWriter; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.HashSet; public class JavaToPdfConverter { // 定义需要着色的Java关键字集合(可按需扩展) private static final Set<String> KEYWORDS = new HashSet<>(); static { KEYWORDS.add("int"); KEYWORDS.add("double"); KEYWORDS.add("new"); KEYWORDS.add("public"); KEYWORDS.add("static"); KEYWORDS.add("void"); KEYWORDS.add("class"); } // 将代码文本拆分为带样式的Chunk列表 private static List<Chunk> splitTextIntoStyledChunks(String text, Font defaultFont, Font keywordFont) { List<Chunk> chunks = new ArrayList<>(); StringBuilder currentWord = new StringBuilder(); for (char c : text.toCharArray()) { // 按空白、标点分割单词,避免误匹配关键字片段 if (Character.isWhitespace(c) || isPunctuation(c)) { if (currentWord.length() > 0) { String word = currentWord.toString(); chunks.add(new Chunk(word, KEYWORDS.contains(word) ? keywordFont : defaultFont)); currentWord.setLength(0); } chunks.add(new Chunk(String.valueOf(c), defaultFont)); } else { currentWord.append(c); } } // 处理文本末尾的最后一个单词 if (currentWord.length() > 0) { String word = currentWord.toString(); chunks.add(new Chunk(word, KEYWORDS.contains(word) ? keywordFont : defaultFont)); } return chunks; } // 判断是否为标点符号(可按需扩展符号范围) private static boolean isPunctuation(char c) { return ".,;(){}[]+-*/=<>!".indexOf(c) != -1; } public static void createPDF(String javaContent, String loc) { try { // 加载等宽字体,保证代码排版整齐 BaseFont baseFont = BaseFont.createFont("C:\\Windows\\Fonts\\cour.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED); Font defaultFont = new Font(baseFont, 13, Font.NORMAL, BaseColor.BLACK); // 关键字颜色匹配NetBeans的蓝色风格 Font keywordFont = new Font(baseFont, 13, Font.NORMAL, BaseColor.BLUE); String targetLoc = loc.replace(".java", ".pdf"); Document document = new Document(); PdfWriter.getInstance(document, new FileOutputStream(targetLoc)); document.open(); Paragraph paragraph = new Paragraph(); // 将带样式的Chunk依次添加到段落 List<Chunk> chunks = splitTextIntoStyledChunks(javaContent, defaultFont, keywordFont); for (Chunk chunk : chunks) { paragraph.add(chunk); } document.add(paragraph); document.close(); } catch (Exception e) { e.printStackTrace(); } } // 测试用例 public static void main(String[] args) { String sampleCode = "public class TestDemo {\n public static void main(String[] args) {\n int count = 0;\n double total = 19.98;\n Demo obj = new Demo();\n }\n}"; createPDF(sampleCode, "TestDemo.java"); } }
关键细节说明
- 关键字匹配:用
HashSet存储关键字,查询效率更高,避免误匹配变量名中包含关键字片段的情况。 - 文本拆分逻辑:通过空白和标点分割单词,保证关键字被精准识别。
- 字体选择:使用等宽字体(如Courier),还原IDE中代码的排版效果。
如果需要支持更多关键字,直接向KEYWORDS集合中添加即可,无需修改核心逻辑。
内容的提问来源于stack exchange,提问作者SchlappiHoppel
相关产品推荐
相关产品推荐

