对比新文件 |
| | |
| | | /* |
| | | * Copyright 2014-2020 Sayi |
| | | * |
| | | * Licensed under the Apache License, Version 2.0 (the "License"); |
| | | * you may not use this file except in compliance with the License. |
| | | * You may obtain a copy of the License at |
| | | * |
| | | * http://www.apache.org/licenses/LICENSE-2.0 |
| | | * |
| | | * Unless required by applicable law or agreed to in writing, software |
| | | * distributed under the License is distributed on an "AS IS" BASIS, |
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| | | * See the License for the specific language governing permissions and |
| | | * limitations under the License. |
| | | */ |
| | | package com.ruoyi.inspect.util; |
| | | |
| | | import com.deepoove.poi.XWPFTemplate; |
| | | import com.deepoove.poi.exception.RenderException; |
| | | import com.deepoove.poi.policy.RenderPolicy; |
| | | import com.deepoove.poi.render.compute.RenderDataCompute; |
| | | import com.deepoove.poi.render.processor.DocumentProcessor; |
| | | 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.*; |
| | | 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; |
| | | |
| | | /** |
| | | * Hack for loop table row |
| | | * |
| | | * @author Sayi |
| | | * |
| | | */ |
| | | public class HackLoopTableRenderPolicy implements RenderPolicy { |
| | | |
| | | private String prefix; |
| | | private String suffix; |
| | | private boolean onSameLine; |
| | | |
| | | public HackLoopTableRenderPolicy() { |
| | | this(false); |
| | | } |
| | | |
| | | public HackLoopTableRenderPolicy(boolean onSameLine) { |
| | | this("[", "]", onSameLine); |
| | | } |
| | | |
| | | public HackLoopTableRenderPolicy(String prefix, String suffix) { |
| | | this(prefix, suffix, false); |
| | | } |
| | | |
| | | public HackLoopTableRenderPolicy(String prefix, String suffix, boolean onSameLine) { |
| | | this.prefix = prefix; |
| | | this.suffix = suffix; |
| | | this.onSameLine = onSameLine; |
| | | } |
| | | |
| | | @Override |
| | | public void render(ElementTemplate eleTemplate, Object data, XWPFTemplate template) { |
| | | RunTemplate runTemplate = (RunTemplate) eleTemplate; |
| | | XWPFRun run = runTemplate.getRun(); |
| | | try { |
| | | if (!TableTools.isInsideTable(run)) { |
| | | throw new IllegalStateException( |
| | | "The template tag " + runTemplate.getSource() + " must be inside a table"); |
| | | } |
| | | XWPFTableCell tagCell = (XWPFTableCell) ((XWPFParagraph) run.getParent()).getBody(); |
| | | XWPFTable table = tagCell.getTableRow().getTable(); |
| | | run.setText("", 0); |
| | | |
| | | int templateRowIndex = getTemplateRowIndex(tagCell); |
| | | 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; |
| | | while (iterator.hasNext()) { |
| | | insertPosition = templateRowIndex++; |
| | | XWPFTableRow nextRow = table.insertNewTableRow(insertPosition); |
| | | setTableRow(table, templateRow, insertPosition); |
| | | |
| | | // double set row |
| | | XmlCursor newCursor = templateRow.getCtRow().newCursor(); |
| | | newCursor.toPrevSibling(); |
| | | XmlObject object = newCursor.getObject(); |
| | | nextRow = new XWPFTableRow((CTRow) object, table); |
| | | if (!firstFlag) { |
| | | // update VMerge cells for non-first row |
| | | List<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(iterator.next()); |
| | | 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); |
| | | } catch (Exception e) { |
| | | throw new RenderException("HackLoopTable for " + eleTemplate + "error: " + e.getMessage(), e); |
| | | } |
| | | } |
| | | |
| | | 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); |
| | | } |
| | | |
| | | } |