You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在iText生成的PDF中为Java关键字添加颜色?

解决Java文件转PDF时关键字着色问题

你的问题核心在于ANSI颜色转义码是终端输出专用编码,iText无法识别,必须改用iText原生的文本样式控制方式——通过Chunk对象分别定义普通文本和关键字的显示样式。

实现思路

  1. 摒弃ANSI标记方案,直接在PDF生成流程中处理文本:将原Java代码拆分为普通文本片段和关键字片段。
  2. 为关键字片段单独设置指定颜色的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 02:05:31