前言:
现在兄弟们对“div嵌套div布局如何爬”大概比较着重,姐妹们都需要剖析一些“div嵌套div布局如何爬”的相关资讯。那么小编在网络上汇集了一些关于“div嵌套div布局如何爬””的相关内容,希望各位老铁们能喜欢,兄弟们一起来了解一下吧!依赖包版本:
<!--poi-tl word支持--><dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.10.4</version></dependency><!--poi-tl html转word插件支持--><dependency> <groupId>io.github.draco1023</groupId> <artifactId>poi-tl-ext</artifactId> <version>0.4.1</version></dependency>
普通情况下使用方式:
// 定义一个html渲染策略HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy();Configure configure = Configure.builder() .bind("html", htmlRenderPolicy) .build();
word模板:
遇到问题:当html存在块级元素嵌套,如div嵌套div,则会出现空白段落问题,嵌套几层,就出现几个空白段落,这与html在web页面渲染的效果不一致。嵌套的html段落如下:
<div class="xxx"> <div class="xxx"> <p>你好!</p> </div> </div>
渲染效果:
原因:经过查看poi-tl-ext源码(org.ddr.poi.html.HtmlRenderContext.renderElement(Element element)),发现,当遇到【块级元素】时,会自动生成一个新的段落,虽然也存在空白段落问题的处理,但是为什么没有处理到这种情况,暂时还不清楚。
初步解决方案:利用org.ddr.poi.html.HtmlRenderContext.renderElement提供的markDedupe()和unmarkDedupe(),然后自定义div(或者其它标签)标签的渲染逻辑。
改进后的方案:
一、新增块级元素(div示例)的渲染策略:
import org.apache.commons.lang3.StringUtils;import org.ddr.poi.html.ElementRenderer;import org.ddr.poi.html.HtmlRenderContext;import org.jsoup.nodes.Element;import org.jsoup.nodes.Node;import java.util.Objects;/** * @description: div渲染 * @author: xx * @create: 2022-11-16 17:01:56 **/public class BlockRenderer implements ElementRenderer { private static final String[] TAGS = {"div", "p"}; /** * 开始渲染 * * @param element HTML元素 * @param context 渲染上下文 * @return 是否继续渲染子元素 */ @Override public boolean renderStart(Element element, HtmlRenderContext context) { // 如果当前块级元素,存在内容 String ownText = element.ownText(); if (StringUtils.isNotBlank(ownText)) { return true; } Node firstNode = element.childNode(0); // 如果没有子元素,则返回 if (Objects.isNull(firstNode)) { return true; } // 判断第一个子元素是否是块级元素 if (firstNode instanceof Element) { Element firstChildElement = ((Element) firstNode); if (firstChildElement.isBlock()) { // 如果是,则当前块级元素不生成新的段落,否则会形成空白行 context.markDedupe(context.getClosestParagraph()); } } return true; } /** * 元素渲染结束需要执行的逻辑 * * @param element HTML元素 * @param context 渲染上下文 */ @Override public void renderEnd(Element element, HtmlRenderContext context) { context.unmarkDedupe(); }/*** 支持的标签*/ @Override public String[] supportedTags() { return TAGS; } /** * 是否渲染为块级元素,如果是,则创建新段落 * */ @Override public boolean renderAsBlock() { return true; }}
二、配置html的渲染策略:
import org.ddr.poi.html.ElementRenderer;import org.ddr.poi.html.HtmlRenderConfig;import org.ddr.poi.html.HtmlRenderPolicy;import java.util.ArrayList;import java.util.List;import java.util.Objects;/** * @description: html渲染策略 * @author: * @create: 2022-11-17 09:13:37 **/public class HtmlRenderPolicyConfig { /** * 获取html渲染策略 * * @return */ public static HtmlRenderPolicy getHtmlRenderPolicy() { HtmlRenderConfig htmlRenderConfig = new HtmlRenderConfig(); List<ElementRenderer> customRenderers = htmlRenderConfig.getCustomRenderers(); if (Objects.isNull(customRenderers)) { customRenderers = new ArrayList<>(4); } // 装载自定义的标签渲染器策略 customRenderers.add(new BlockRenderer()); htmlRenderConfig.setCustomRenderers(customRenderers); HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy(htmlRenderConfig); return htmlRenderPolicy; }}
三、使用方式不变:
Configure configure = Configure.builder() .bind("html", HtmlRenderPolicyConfig.getHtmlRenderPolicy()) .build();
四、效果:
总结:目前暂时不知道这种解决方案,有可能带来的其它影响,因为目前业务上,以及使用的测试html字符串不是太复杂,所以达不到普适性,参考时,请根据实际=情况自行处理。
标签: #div嵌套div布局如何爬 #div的多层嵌套 #java引入poi依赖包 #cssdiv嵌套 #表格嵌套表格 element