当前位置: 首页 > news >正文

聊城微信推广网站seo推广软件代理

聊城微信推广网站,seo推广软件代理,桂林做网站,进出口纠纷上海企业服务云目录 问题解决问题poi-tl介绍 功能实现引入依赖模版代码效果图 附加(插件实现)MergeColumnData 对象MergeGroupData 类ServerMergeTableData 数据信息ServerMergeTablePolicy 合并插件 问题 由于在开发功能需求中,word文档需要垂直合并表格&…

目录

    • 问题
    • 解决问题
      • poi-tl介绍
    • 功能实现
      • 引入依赖
      • 模版
      • 代码
      • 效果图
    • 附加(插件实现)
      • MergeColumnData 对象
      • MergeGroupData 类
      • ServerMergeTableData 数据信息
      • ServerMergeTablePolicy 合并插件

问题

由于在开发功能需求中,word文档需要垂直合并表格,而word模版引擎原有的插件功能只能做行循环,不满足需求;

解决问题

  • 目前选择的poi-tl的模版引擎,在原有的基础上新增自定义插件来实现功能

poi-tl介绍

poi-tl 是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,你可以非常方便的加入到你的项目中;

Word模板引擎功能描述
文本将标签渲染为文本
图片将标签渲染为图片
表格将标签渲染为表格
图表条形图(3D条形图)、柱形图(3D柱形图)、面积图(3D面积图)、折线图(3D折线图)、雷达图、饼图(3D饼图)、散点图等图表渲染
If Condition判断根据条件隐藏或者显示某些文档内容(包括文本、段落、图片、表格、列表、图表等)
Foreach Loop循环根据集合循环某些文档内容(包括文本、段落、图片、表格、列表、图表等)
Loop表格行循环复制渲染表格的某一行
Loop表格列循环复制渲染表格的某一列
Loop有序列表支持有序列表的循环,同时支持多级列表
Highlight代码高亮word中代码块高亮展示,支持26种语言和上百种着色样式
Markdown将Markdown渲染为word文档
Word批注完整的批注功能,创建批注、修改批注等
Word附件Word中插入附件
SDT内容控件内容控件内标签支持
Textbox文本框文本框内标签支持
图片替换将原有图片替换成另一张图片
书签、锚点、超链接支持设置书签,文档内锚点和超链接功能
Expression Language完全支持SpringEL表达式,可以扩展更多的表达式:OGNL, MVEL
样式支持有序列表的循环,同时支持多级列表
模板嵌套模板包含子模板,子模板再包含子模板
模板嵌套模板包含子模板,子模板再包含子模板
合并Word合并Merge,也可以在指定位置进行合并
用户自定义函数(插件)插件化设计,在文档任何位置执行函数

功能实现

引入依赖

		<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-full</artifactId><version>5.2.5</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.5</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.5</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.25</version></dependency><!-- spring el表达式 --><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>5.3.18</version></dependency>

模版

在这里插入图片描述

代码

@Testpublic void test() throws Exception {Configure config = Configure.builder().bind("precipitationInfoList", new ServerMergeTablePolicy()).useSpringEL(false).build();Map<String, Object> dataMap = new HashMap<String, Object>();dataMap.put("precipitationInfoList", getServerMergeTableData());ClassPathResource classPathResource = new ClassPathResource("static/word/template.docx");try (InputStream resourceInputStream = classPathResource.getInputStream();XWPFTemplate template = XWPFTemplate.compile(resourceInputStream, config);) {template.render(dataMap);template.writeAndClose(new FileOutputStream("output.docx"));} catch (Exception e) {e.printStackTrace();}}private ServerMergeTableData getServerMergeTableData() {List<Map<String,Object>> serverDataList = new ArrayList<>();Map<String,Object> serverData1 = new HashMap<>();serverData1.put("province","广东省");serverData1.put("city","深圳市");serverData1.put("precipitation","0.3");serverDataList.add(serverData1);Map<String,Object> serverData2 = new HashMap<>();serverData2.put("province","广东省");serverData2.put("city","广州市");serverData2.put("precipitation","5.1");serverDataList.add(serverData2);Map<String,Object> serverData3 = new HashMap<>();serverData3.put("province","广东省");serverData3.put("city","东莞市");serverData3.put("precipitation","10");serverDataList.add(serverData3);Map<String,Object> serverData4 = new HashMap<>();serverData4.put("province","湖南");serverData4.put("city","长沙");serverData4.put("precipitation","10");serverDataList.add(serverData4);Map<String,Object> serverData6 = new HashMap<>();serverData6.put("province","湖南");serverData6.put("city","湘潭");serverData6.put("precipitation","4.5");serverDataList.add(serverData6);List<MergeGroupData> groupDataList = new ArrayList<>();groupDataList.add(MergeGroupData.builder().indexList(Arrays.asList("0","1","2")).build());groupDataList.add(MergeGroupData.builder().indexList(Arrays.asList("3","4")).build());List<MergeColumnData> mergeColumns = new ArrayList<>();mergeColumns.add(MergeColumnData.builder().groupDataList(groupDataList).mergeColumn(0).build());ServerMergeTableData serverMergeTableData = new ServerMergeTableData();serverMergeTableData.setMergeColumns(mergeColumns);serverMergeTableData.setServerDataList(serverDataList);return serverMergeTableData;}

效果图

在这里插入图片描述

附加(插件实现)

MergeColumnData 对象


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.List;@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class MergeColumnData {/*** 携带要分组的信息*/private List<MergeGroupData> groupDataList;/*** 需要合并的列,从0开始*/private Integer mergeColumn;
}

MergeGroupData 类


/*** 合并对象信息*/
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class MergeGroupData {/*** 名称*/private List<String> indexList;public Integer getListSize() {if (Objects.isNull(indexList)) {return 0;}return indexList.size();}
}

ServerMergeTableData 数据信息


import lombok.Data;import java.util.List;@Data
public class ServerMergeTableData {private List<?> serverDataList;/*** 列合并信息*/private List<MergeColumnData> mergeColumns;
}

ServerMergeTablePolicy 合并插件


import cn.hutool.core.collection.CollUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.exception.RenderException;
import com.deepoove.poi.policy.AbstractRenderPolicy;
import com.deepoove.poi.render.RenderContext;
import com.deepoove.poi.render.compute.EnvModel;
import com.deepoove.poi.render.compute.RenderDataCompute;
import com.deepoove.poi.render.processor.DocumentProcessor;
import com.deepoove.poi.render.processor.EnvIterator;
import com.deepoove.poi.resolver.TemplateResolver;
import com.deepoove.poi.template.ElementTemplate;
import com.deepoove.poi.template.MetaTemplate;
import com.deepoove.poi.template.run.RunTemplate;
import com.deepoove.poi.util.ReflectionUtils;
import com.deepoove.poi.util.TableTools;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;import java.util.Iterator;
import java.util.List;public class ServerMergeTablePolicy extends AbstractRenderPolicy<ServerMergeTableData> {private String prefix;private String suffix;private boolean onSameLine;public ServerMergeTablePolicy() {this(false);}public ServerMergeTablePolicy(boolean onSameLine) {this("[", "]", onSameLine);}public ServerMergeTablePolicy(String prefix, String suffix) {this(prefix, suffix, false);}public ServerMergeTablePolicy(String prefix, String suffix, boolean onSameLine) {this.prefix = prefix;this.suffix = suffix;this.onSameLine = onSameLine;}@Overridepublic void doRender(RenderContext<ServerMergeTableData> context) throws Exception {XWPFTemplate template = context.getTemplate();ServerMergeTableData mergeTableData = context.getData();ElementTemplate eleTemplate = context.getEleTemplate();this.renderTo(eleTemplate, mergeTableData, template);}public void renderTo(ElementTemplate eleTemplate, Object tableData, XWPFTemplate template) {RunTemplate runTemplate = (RunTemplate) eleTemplate;XWPFRun run = runTemplate.getRun();try {XWPFTableCell tagCell = (XWPFTableCell) ((XWPFParagraph) run.getParent()).getBody();XWPFTable table = tagCell.getTableRow().getTable();run.setText("", 0);if (null == tableData) {return;}ServerMergeTableData serverTableData = (ServerMergeTableData) tableData;List data = serverTableData.getServerDataList();if (!TableTools.isInsideTable(run)) {throw new IllegalStateException("The template tag " + runTemplate.getSource() + " must be inside a table");}int templateRowIndex = getTemplateRowIndex(tagCell);int tempStartRow = templateRowIndex;if (null != data && data instanceof Iterable) {Iterator<?> iterator = ((Iterable<?>) data).iterator();XWPFTableRow templateRow = table.getRow(templateRowIndex);int insertPosition = templateRowIndex;TemplateResolver resolver = new TemplateResolver(template.getConfig().copy(prefix, suffix));boolean firstFlag = true;int index = 0;boolean hasNext = iterator.hasNext();while (hasNext) {Object root = iterator.next();hasNext = iterator.hasNext();insertPosition = templateRowIndex++;XWPFTableRow nextRow = table.insertNewTableRow(insertPosition);setTableRow(table, templateRow, insertPosition);// double set rowXmlCursor newCursor = templateRow.getCtRow().newCursor();newCursor.toPrevSibling();XmlObject object = newCursor.getObject();nextRow = new XWPFTableRow((CTRow) object, table);if (!firstFlag) {// update VMerge cells for non-first rowList<XWPFTableCell> tableCells = nextRow.getTableCells();for (XWPFTableCell cell : tableCells) {CTTcPr tcPr = TableTools.getTcPr(cell);CTVMerge vMerge = tcPr.getVMerge();if (null == vMerge) continue;if (STMerge.RESTART == vMerge.getVal()) {vMerge.setVal(STMerge.CONTINUE);}}} else {firstFlag = false;}setTableRow(table, nextRow, insertPosition);RenderDataCompute dataCompute = template.getConfig().getRenderDataComputeFactory().newCompute(EnvModel.of(root, EnvIterator.makeEnv(index++, hasNext)));List<XWPFTableCell> cells = nextRow.getTableCells();cells.forEach(cell -> {List<MetaTemplate> templates = resolver.resolveBodyElements(cell.getBodyElements());new DocumentProcessor(template, resolver, dataCompute).process(templates);});}}table.removeRow(templateRowIndex);afterloop(table, data);//合并表格信息mergeTable(serverTableData, tempStartRow, table);} catch (Exception e) {throw new RenderException("HackLoopTable for " + eleTemplate + " error: " + e.getMessage(), e);}}private void mergeTable(ServerMergeTableData serverMergeTableData, int startRow, XWPFTable xwpfTable) {List serverDataList = serverMergeTableData.getServerDataList();List<MergeColumnData> mergeColumns = serverMergeTableData.getMergeColumns();if (CollUtil.isNotEmpty(mergeColumns)) {for (int i = 0; i < serverDataList.size(); i++) {for (MergeColumnData mergeColumnData : mergeColumns) {Integer mergeColumn = mergeColumnData.getMergeColumn();List<MergeGroupData> groupDataList = mergeColumnData.getGroupDataList();for (int j = 0; j < groupDataList.size(); j++) {MergeGroupData mergeGroupData = groupDataList.get(j);List<String> indexList = mergeGroupData.getIndexList();int listSize = mergeGroupData.getListSize();if (listSize == 1) {continue;}// 若匹配上 就直接合并if (indexList.contains(i + "")) {int col = i + startRow;int fromRow = i + (startRow - 1) + listSize;TableTools.mergeCellsVertically(xwpfTable, mergeColumn, col, fromRow);groupDataList.remove(j);break;}}}}}}private int getTemplateRowIndex(XWPFTableCell tagCell) {XWPFTableRow tagRow = tagCell.getTableRow();return onSameLine ? getRowIndex(tagRow) : (getRowIndex(tagRow) + 1);}protected void afterloop(XWPFTable table, Object data) {}@SuppressWarnings("unchecked")private void setTableRow(XWPFTable table, XWPFTableRow templateRow, int pos) {List<XWPFTableRow> rows = (List<XWPFTableRow>) ReflectionUtils.getValue("tableRows", table);rows.set(pos, templateRow);table.getCTTbl().setTrArray(pos, templateRow.getCtRow());}private int getRowIndex(XWPFTableRow row) {List<XWPFTableRow> rows = row.getTable().getRows();return rows.indexOf(row);}
}

文章转载自:
http://dinncowily.bkqw.cn
http://dinncoforeshock.bkqw.cn
http://dinncooctroi.bkqw.cn
http://dinncoinculpate.bkqw.cn
http://dinncodou.bkqw.cn
http://dinncocivil.bkqw.cn
http://dinncoterseness.bkqw.cn
http://dinncohertha.bkqw.cn
http://dinncoburletta.bkqw.cn
http://dinncoimmit.bkqw.cn
http://dinncodivide.bkqw.cn
http://dinncoqoph.bkqw.cn
http://dinncodelimitation.bkqw.cn
http://dinncoclubhouse.bkqw.cn
http://dinncotypology.bkqw.cn
http://dinncolymphangiogram.bkqw.cn
http://dinncostaffwork.bkqw.cn
http://dinncoamoretto.bkqw.cn
http://dinncosemidiameter.bkqw.cn
http://dinncopresort.bkqw.cn
http://dinncoarcover.bkqw.cn
http://dinncomolasses.bkqw.cn
http://dinncoterminate.bkqw.cn
http://dinncospicate.bkqw.cn
http://dinncoimprovisatore.bkqw.cn
http://dinncolaryngeal.bkqw.cn
http://dinncomoray.bkqw.cn
http://dinncogemmate.bkqw.cn
http://dinncogranny.bkqw.cn
http://dinncoquotability.bkqw.cn
http://dinncocompounder.bkqw.cn
http://dinncopeppercorn.bkqw.cn
http://dinncowristband.bkqw.cn
http://dinncoknotwork.bkqw.cn
http://dinncoretentively.bkqw.cn
http://dinncooutage.bkqw.cn
http://dinncocosmea.bkqw.cn
http://dinncotitoism.bkqw.cn
http://dinncoinvited.bkqw.cn
http://dinncoaskari.bkqw.cn
http://dinncopleistocene.bkqw.cn
http://dinncocommunity.bkqw.cn
http://dinncowearisome.bkqw.cn
http://dinncofidelity.bkqw.cn
http://dinncooogamete.bkqw.cn
http://dinncogametocide.bkqw.cn
http://dinncoostensive.bkqw.cn
http://dinncooxygen.bkqw.cn
http://dinncoinstruction.bkqw.cn
http://dinncocirrhotic.bkqw.cn
http://dinncostadholder.bkqw.cn
http://dinncoalkahest.bkqw.cn
http://dinncowhiplike.bkqw.cn
http://dinncofeverweed.bkqw.cn
http://dinncopolarisation.bkqw.cn
http://dinncoknuckler.bkqw.cn
http://dinncoforegrounding.bkqw.cn
http://dinncoiberis.bkqw.cn
http://dinncopedate.bkqw.cn
http://dinncosiquis.bkqw.cn
http://dinncounisex.bkqw.cn
http://dinncoenergize.bkqw.cn
http://dinncofairy.bkqw.cn
http://dinncocheloid.bkqw.cn
http://dinncowushu.bkqw.cn
http://dinncopresbyterianism.bkqw.cn
http://dinncohercules.bkqw.cn
http://dinncoassociationism.bkqw.cn
http://dinncoglenoid.bkqw.cn
http://dinncofontina.bkqw.cn
http://dinncopolydymite.bkqw.cn
http://dinncomylohyoid.bkqw.cn
http://dinnconegatory.bkqw.cn
http://dinncoarchdiocese.bkqw.cn
http://dinncocircumgalactic.bkqw.cn
http://dinncomucilage.bkqw.cn
http://dinncovulpecular.bkqw.cn
http://dinncopolyandric.bkqw.cn
http://dinncopapillary.bkqw.cn
http://dinncoinnkeeper.bkqw.cn
http://dinncomotivate.bkqw.cn
http://dinncovideoland.bkqw.cn
http://dinncoliturgism.bkqw.cn
http://dinncohistoriography.bkqw.cn
http://dinncorooinek.bkqw.cn
http://dinncohorsemint.bkqw.cn
http://dinncozenist.bkqw.cn
http://dinncoetceteras.bkqw.cn
http://dinncopasteurization.bkqw.cn
http://dinncobareback.bkqw.cn
http://dinncoconcuss.bkqw.cn
http://dinncoindeliberateness.bkqw.cn
http://dinncobiobibliography.bkqw.cn
http://dinncopuzzleheaded.bkqw.cn
http://dinncoriverside.bkqw.cn
http://dinncobowsman.bkqw.cn
http://dinncoverein.bkqw.cn
http://dinncopledger.bkqw.cn
http://dinncohomopolar.bkqw.cn
http://dinncothereunder.bkqw.cn
http://www.dinnco.com/news/86563.html

相关文章:

  • 南充疫情最新情况seo在线短视频发布页运营
  • 举例一个成功的网络营销案例广州网站优化外包
  • 抖音小程序句容市网站seo优化排名
  • 西宁做网站最好的公司好搜搜索引擎
  • 做视频开头的网站产品品牌推广策划方案
  • 免费爱做网站凡科建站怎么样
  • dede世界杯网站模板百度快照收录入口
  • 网站前端做报名框seo外链购买
  • phpcms做企业网站授权北京seo如何排名
  • 遂川网站建设关键词搜索热度查询
  • 做公司网站写什么信息南宁seo外包服务
  • 可以拔下来做的网站吗淘大象排名查询
  • 站内推广的方式有哪些百度广告运营
  • 做旅游的网站有哪些制作一个网站的全过程
  • 门头沟网站开发怎么自己建立网站
  • 合肥营销型网站建设公司关键词排名查询api
  • 地税局网站怎么做变更seo排名的方法
  • 外网访问wordpress版式不对网站优化查询
  • 个人网站备案能几个大连百度推广公司
  • 网站案例介绍网络公关
  • 网站在百度搜不到seo课程培训班
  • 优秀设计师个人网站向日葵seo
  • 怎样查看wordpress用的什么主题天津优化代理
  • 德保县建设局的网站关键词排名批量查询软件
  • b站推广深夜app宁波seo运营推广平台排名
  • 树莓派可以做网站的服务器吗软文营销的技巧有哪些?
  • 枣阳建设局网站首页微信营销的成功案例
  • 接私活做预算的网站长治seo
  • 张家口建站优化快速优化网站排名的方法
  • 做微信投票的网站推广普通话海报