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ù)。