poi-tl-ext + poi-tl-plugin-highlight让html字符串转word并且代码块高亮(如果存在代码块)

poi-tl:1.12.2
poi-tl-ext:0.4.23-poi5
poi-tl-plugin-highlight:1.0.0
根据对应版本实现 poi-tl-ext + HighlightRenderPolicy 编写新插件 让html字符串转word并且代码块高亮(如果存在代码块)
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.plugin.highlight.HighlightRenderData;
import com.deepoove.poi.plugin.highlight.HighlightRenderPolicy;
import com.deepoove.poi.plugin.highlight.HighlightStyle;
import com.deepoove.poi.policy.AbstractRenderPolicy;
import com.deepoove.poi.render.RenderContext;
import com.deepoove.poi.template.run.RunTemplate;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.ddr.poi.html.HtmlRenderPolicy;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class HtmlHighlightRenderPolicy extends AbstractRenderPolicy<String> {

    private final HtmlRenderPolicy htmlPolicy = new HtmlRenderPolicy();
    private final HighlightRenderPolicy highlightPolicy = new HighlightRenderPolicy();

    @Override
    public void doRender(RenderContext<String> context) {
        String html = context.getData();
        if (html == null || html.trim().isEmpty()) return;

        Document doc = Jsoup.parseBodyFragment(html);
        Elements codes = doc.select("pre > code");

        // 没有代码块:直接走 HTML
        if (codes.isEmpty()) {
            htmlPolicy.render(context.getEleTemplate(), html, context.getTemplate());
            return;
        }

        RunTemplate runTemplate = (RunTemplate) context.getEleTemplate();
        XWPFParagraph paragraph = runTemplate.getRun().getParagraph();
        XWPFTemplate template = context.getTemplate();

        // ① 立刻清掉占位符(此后不再使用旧 run)
        paragraph.removeRun(paragraph.getRuns().indexOf(runTemplate.getRun()));

        // 逐节点处理
        for (Element node : doc.body().children()) {

            // 代码块
            if ("pre".equals(node.tagName()) && node.selectFirst("code") != null) {
                Element code = node.selectFirst("code");
                String language = parseLanguage(node.className());
                String codeText = code.text();

                XWPFParagraph codePara = paragraph.getBody().insertNewParagraph(paragraph.getCTP().newCursor());
                XWPFRun codeRun = codePara.createRun();

                HighlightRenderData data = new HighlightRenderData();
                data.setCode(codeText);
                data.setLanguage(language);
                data.setStyle(HighlightStyle.builder().withShowLine(false).withTheme("zenburn").build());

                highlightPolicy.render(
                        new RunTemplate("",codeRun),
                        data,
                        template
                );
            }
            // 普通 HTML
            else {
                XWPFParagraph htmlPara = paragraph.getBody().insertNewParagraph(paragraph.getCTP().newCursor());
                XWPFRun htmlRun = htmlPara.createRun();
                htmlPolicy.render(
                        new RunTemplate("",htmlRun),
                        node.outerHtml(),
                        template
                );
            }
        }
    }

    @Override
    protected void afterRender(RenderContext<String> context) {
        // 已手动清理,这里不再 clearPlaceholder
    }

    private String parseLanguage(String className) {
        if (className != null && className.startsWith("language-")) {
            return className.substring("language-".length());
        }
        return "text";
    }
}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容