poi-tl-ext + poi-tl-plugin-highlight讓html字符串轉(zhuǎn)word并且代碼塊高亮(如果存在代碼塊)

poi-tl:1.12.2
poi-tl-ext:0.4.23-poi5
poi-tl-plugin-highlight:1.0.0
根據(jù)對應(yīng)版本實現(xiàn) poi-tl-ext + HighlightRenderPolicy 編寫新插件 讓html字符串轉(zhuǎn)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()));

        // 逐節(jié)點處理
        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";
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容