package org.example.Office;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.spire.doc.*;
import com.spire.doc.documents.*;
import com.spire.doc.fields.DocPicture;
import com.spire.doc.fields.TextBox;
import com.spire.doc.fields.TextRange;
import com.spire.doc.formatting.CharacterFormat;
import com.spire.doc.formatting.ParagraphFormat;
import org.apache.commons.io.FilenameUtils;
import org.example.Utils.NativeExtensionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static org.example.Utils.NativeExtensionUtils.TrimEnd;
import static org.example.Utils.NativeExtensionUtils.isNullOrEmpty;

@Component
public class CreateWordUtil {
    private static final Logger log = LoggerFactory.getLogger(CreateWordUtil.class);


    @Autowired
    private static JdbcTemplate jdbcTemplate;

    public static boolean Create(String mainTempPath, String menuTempPath, String menuTempArray,
                                 List<List<List<Map<String, Object>>>>  dataSets, String savePath, String OAUrl,
                                 StringBuilder msg) {
        // 调用原始方法，传入默认参数 false
        return Create(mainTempPath, menuTempPath, menuTempArray, dataSets, savePath, OAUrl, msg, false);
    }
    public static boolean Create(String mainTempPath, String menuTempPath, String menuTempArray,
                                 List<List<List<Map<String, Object>>>> dataSets, String savePath, String OAUrl,
                                 StringBuilder msg, boolean createPdf) {
        msg.setLength(0); // 初始化消息（对应C#的msg = ""）
        boolean result = false;
        Document saveDocument = null;

        try {
            saveDocument = new Document(); // 初始化文档对象（对应C#的new Document()）

            // 遍历数据集，调用工具类方法填充文档内容（与C# foreach逻辑一致）
            for (List<List<Map<String, Object>>> dataSet : dataSets) {  // 每个元素是单个 DataSet 的替代者
                InitTempDocuemnt(saveDocument, mainTempPath, menuTempPath, menuTempArray, dataSet);
                InitCreatBaseSql(saveDocument, dataSet, OAUrl);
                InitCreatBaseSqlDetail(saveDocument, dataSet, OAUrl);
                InitCreatTabSql(saveDocument, dataSet, OAUrl);
                InitCreatTabSqlDetail(saveDocument, dataSet, OAUrl);
                RemoveTableRow(saveDocument);
            }

            // 确保保存目录存在（对应C#的Directory.Exists和CreateDirectory）
            File saveDir = new File(savePath).getParentFile();
            if (!saveDir.exists()) {
                saveDir.mkdirs(); // 递归创建目录
            }

            // 构建PDF保存路径（对应C#的fileName拼接）
            String fileName = saveDir.getPath() + File.separator
                    + new File(savePath).getName().replaceFirst("\\.doc$", ".pdf");

            // 保存为Word文档（对应C#的SaveToFile(savePath, FileFormat.Doc)）
            saveDocument.saveToFile(savePath, FileFormat.Doc);

            // 若需要生成PDF，则额外保存（对应C#的if (createPdf)逻辑）
            if (createPdf) {
                saveDocument.saveToFile(fileName, FileFormat.PDF);
            }

            result = true;
            msg.append("生成成功"); // 对应C#的msg += "生成成功"

        } catch (Exception ex) {
            // 异常处理（对应C#的catch块）
            msg.append("生成失败\r\n").append(ex.getMessage()).append("\r\n");
            result = false;
        } finally {
            // 释放资源（对应C#的Close和Dispose）
            if (saveDocument != null) {
                saveDocument.close();
                saveDocument.dispose();
            }
        }

        return result;
    }


    private static Document InitTempDocuemnt(Document document, String mainTempPath, String menuTempPath, String menuTempArray, List<List<Map<String, Object>>> dataSet) {
        if (document == null){
            document = new Document();
        }
        boolean hasMainTemp = false;
        try{
            if(!NativeExtensionUtils.isNullOrEmpty(mainTempPath) && new File(mainTempPath).exists()){
                Section mainSection = new Section(document);
                mainSection.getPageSetup().setDifferentFirstPageHeaderFooter(false);
                document.getSections().add(mainSection);
                hasMainTemp = true;

                Document document2 = new Document();
                document2.loadFromFile(mainTempPath);

                for (Section section : (Iterable<Section>) document2.getSections()) {
                    // 复制页面方向、大小、边距
                    mainSection.getPageSetup().setOrientation(section.getPageSetup().getOrientation());
                    mainSection.getPageSetup().setPageSize(section.getPageSetup().getPageSize());
                    mainSection.getPageSetup().setMargins(section.getPageSetup().getMargins());
                    // 复制页眉页脚
                    CpoyHeaderFooter(section, mainSection, HeaderFooterType.Footer_Even);
                    CpoyHeaderFooter(section, mainSection, HeaderFooterType.Footer_First_Page);
                    CpoyHeaderFooter(section, mainSection, HeaderFooterType.Footer_Odd);
                    CpoyHeaderFooter(section, mainSection, HeaderFooterType.Header_Even);
                    CpoyHeaderFooter(section, mainSection, HeaderFooterType.Header_First_Page);
                    CpoyHeaderFooter(section, mainSection, HeaderFooterType.Header_Odd);

                    // 遍历Section.Body的子对象并克隆添加
                    for (int i = 0; i < section.getBody().getChildObjects().getCount(); i++) {
                        DocumentObject childObject = section.getBody().getChildObjects().get(i);
                        mainSection.getBody().getChildObjects().add(childObject.deepClone());
                    }
                }
            }
            else {
                Section mainSection = new Section(document);
                mainSection.getPageSetup().setDifferentFirstPageHeaderFooter(false);
                document.getSections().add(mainSection);
            }
            if(!NativeExtensionUtils.isNullOrEmpty(menuTempPath) && new File(menuTempPath).exists()){
                if(hasMainTemp){
                    document.getLastSection().getPageSetup().setDifferentFirstPageHeaderFooter(true);
                }
                Document document3 = new Document();
                document3.loadFromFile(menuTempPath);
                if(!NativeExtensionUtils.isNullOrEmpty(menuTempPath)){
                    List<String> ModelStr = new ArrayList<>(Arrays.asList(menuTempArray.split(",")));
                    List<String> AddStrList = new ArrayList<>();
                    for(int i = 0; i<ModelStr.size(); i++){
                        String moduleIdStr = ModelStr.get(i);
                        String index = "";
                        int order = 0;
                        if (moduleIdStr.length() == 8 && moduleIdStr.toLowerCase().startsWith("xmbg")){
                            index = moduleIdStr.substring(4,4);
                            AddStrList.add(moduleIdStr);
                            // 4. 统计列表中等于moduleIdStr的元素个数（替代C#的LINQ Count）
                            for (String str : AddStrList) {
                                if (str.equals(moduleIdStr)) {
                                    order++;
                                }
                            }
                            if (dataSet.size() >= 2) {
                                List<Map<String, Object>> dataTable = dataSet.get(1);
                                if (!dataTable.isEmpty()
                                        && dataTable.get(0).containsKey("crm_lco_xmbg")
                                        && dataTable.get(0).containsKey("crm_lco_order")) {
                                    // 遍历DataTable的每一行（DataRow → Map<String, Object>）
                                    for (Map<String, Object> item : dataTable) {
                                        String crmLcoXmbgVal = String.valueOf(item.get("crm_lco_xmbg"));
                                        String crmLcoOrderVal = String.valueOf(item.get("crm_lco_order"));
                                        String modelStrVal = ModelStr.get(i);
                                        String orderVal = String.valueOf(order);

                                        // 条件判断（等价于C#的Equals）
                                        if (crmLcoXmbgVal.equals(modelStrVal) && crmLcoOrderVal.equals(orderVal)) {
                                            item.put("crm_lco_xmbg", "XMBG_" + order + "_" + index);
                                        }
                                    }
                                }
                            }
                        }
                        String[] moduleIdWithPms = moduleIdStr.split("_");
                        String moduleId = moduleIdWithPms[0];
                        String isBreakPage = moduleIdWithPms.length > 1 ? moduleIdWithPms[1] : "";
                        TextSelection startSelection = document3.findString("{" + moduleId + ":start}", false, true);
                        TextSelection endSelection = document3.findString("{" + moduleId + ":end}", false, true);
                        if (startSelection != null && endSelection != null) {
                            if (moduleId != null && moduleId.equalsIgnoreCase("yw")) {
                                Paragraph lastBreakParagraph = null;
                                DocumentObject lastBreak = null;
                                Section lastSection = document.getLastSection();
                                for (Object obj : lastSection.getParagraphs()) {
                                    if (obj instanceof Paragraph) {
                                        Paragraph paragraph = (Paragraph) obj;

                                        // 内层循环变量名改为objChild（遍历getChildObjects），避免重复
                                        for (Object objChild : paragraph.getChildObjects()) {
                                            if (objChild instanceof DocumentObject) {
                                                DocumentObject docObject = (DocumentObject) objChild;

                                                if (docObject.getDocumentObjectType() == DocumentObjectType.Break) {
                                                    if (docObject instanceof Break) {
                                                        Break breakObject = (Break) docObject;
                                                        if (breakObject.getBreakType() == BreakType.Page_Break) {
                                                            lastBreakParagraph = paragraph;
                                                            lastBreak = docObject;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                if(lastBreakParagraph != null && lastBreak != null){
                                    lastBreakParagraph.getChildObjects().remove(lastBreak);
                                }
                            }
                            Section section = (Section) startSelection.getAsOneRange().getOwnerParagraph().getOwnerTextBody().getOwner();
                            if (section.getPageSetup().getOrientation() != document.getLastSection().getPageSetup().getOrientation()) {
                                // 插入分节符
                                document.getLastSection().getParagraphs().get(document.getLastSection().getParagraphs().getCount() - 1)
                                        .insertSectionBreak(SectionBreakType.No_Break);
// 设置页面方向
                                document.getLastSection().getPageSetup().setOrientation(section.getPageSetup().getOrientation());
// 设置页面大小
                                document.getLastSection().getPageSetup().setPageSize(section.getPageSetup().getPageSize());
// 设置页面边距
                                document.getLastSection().getPageSetup().setMargins(section.getPageSetup().getMargins());
                            }
                            Section mainSection = document.getLastSection();
                            if(!moduleId.equalsIgnoreCase("yw")){
                                CpoyHeaderFooter(section,mainSection,HeaderFooterType.Footer_Even);
                                CpoyHeaderFooter(section,mainSection,HeaderFooterType.Footer_Odd);
                                CpoyHeaderFooter(section,mainSection,HeaderFooterType.Header_Even);
                                CpoyHeaderFooter(section,mainSection,HeaderFooterType.Header_Odd);
                            }
                            boolean isCopying = false;
                            for (Object childObj : section.getBody().getChildObjects()) {
                                if (childObj instanceof DocumentObject) {
                                    DocumentObject obj = (DocumentObject) childObj;
                                    if (obj == startSelection.getAsOneRange().getOwnerParagraph()) {
                                        isCopying = true;
                                        continue;
                                    }
                                    // 判断是否为结束标记段落
                                    if (obj == endSelection.getAsOneRange().getOwnerParagraph()) {
                                        break;
                                    }
                                    // 复制内容到目标区域
                                    if (isCopying) {
                                        DocumentObject documentObject = obj.deepClone(); // 深克隆对象
                                        // 将克隆的内容添加到mainSection的Body子对象中
                                        mainSection.getBody().getChildObjects().add(documentObject);
                                    }
                                }
                            }
                        }
                        // 先判空避免空指针，再判断长度+以XMBG开头（序数规则忽略大小写）
                        if (moduleIdStr != null && moduleIdStr.length() == 8
                                && moduleIdStr.substring(0, 4).equalsIgnoreCase("XMBG")) {
                            // 替代replaceTextRange：查找文本并替换（匹配整词、忽略大小写）
                            TextSelection selection;
                            while ((selection = document.findString(moduleIdStr, false, true)) != null) {
                                selection.getAsOneRange().setText("XMBG_" + order + "_" + index);
                            }

                            // 保留原有的replace方法（双重保障，也可仅用上面的循环）
                            document.replace(moduleIdStr, "XMBG_" + order + "_" + index, false, true);
                        }
                    }
                }
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return document;
    }


    private static void InitCreatBaseSql(Document document, List<List<Map<String, Object>>> dataSet, String OAUrl) {
        for (int i = 0; i < dataSet.size(); i++) {
            String data = "Data" + (i + 1);
            List<Map<String, Object>> dataTable = dataSet.get(i); // 对应C#的dataSet.Tables[i]

            // 获取列名集合（对应C#的dataSet.Tables[i].Columns）
            Set<String> columnNames = dataTable.isEmpty() ? Set.of() : dataTable.get(0).keySet();
            for (String dataColumn : columnNames) { // 遍历列名
                // 获取第一行数据（对应C#的dataTable.Rows[0]）
                Map<String, Object> dataRow = dataTable.size() > 0 ? dataTable.get(0) : null;

                // 处理!{DataX.Column}占位符
                String speciesItem = "!{" + data + "." + dataColumn + "}";
                TextSelection[] speciesContains = document.findAllString(speciesItem, false, true);

                if (speciesContains != null && speciesContains.length > 0) {
                    String cellValue = dataRow.get(dataColumn) == null ? "" : dataRow.get(dataColumn).toString();

                    if (cellValue.equals("/")) {
                        replaceTextRange(document,speciesItem, "!/", false, true);
                        document.replace(speciesItem, "!/", false, true);
                    } else {
                        replaceTextRange(document,speciesItem, cellValue, false, true);
                        document.replace(speciesItem, cellValue, false, true);
                    }
                    // 处理{DataX.Column}占位符
                    String item = "{" + data + "." + dataColumn + "}";
                    TextSelection[] contains = document.findAllString(item, false, true);
                    if (contains != null && contains.length > 0) {
                        if(dataRow != null){
                            String columnValue = dataRow.get(dataColumn) + "";
                            // 处理图片列（img_前缀）
                            if (dataColumn.contains("img_")) {
                                Image image = null;
                                Dimension size = new Dimension(200, 200);
                                String picUrl = columnValue;
                                if (picUrl.startsWith("@") && jdbcTemplate != null){
                                    List<Map<String, Object>> picTable = jdbcTemplate.queryForList(picUrl.substring(1));
                                    if (picTable != null && !picTable.isEmpty()){
                                        Map<String, Object> picRow = picTable.get(0);
                                        String path = picRow.containsKey("value") ? (picRow.get("value") + "") : "";
                                        int width = 200;
                                        int height = 200;

                                        if (picRow.containsKey("width")) {
                                            try {
                                                width = Integer.parseInt(picRow.get("width") + "");
                                            } catch (NumberFormatException e) {
                                                width = 200;
                                            }
                                        }
                                        if (picRow.containsKey("height")) {
                                            try {
                                                height = Integer.parseInt(picRow.get("height") + "");
                                            } catch (NumberFormatException e) {
                                                height = 200;
                                            }
                                        }
                                        size = new Dimension(width, height);
                                        image = InitCreatImage(path, OAUrl);
                                    }
                                }
                                else {
                                    image = InitCreatImage(picUrl, OAUrl);
                                    if (image == null) {
                                        image = Base64ToImage(columnValue);
                                    }
                                }
                                TextSelection[] selections = document.findAllString(item, false, true);
                                for (TextSelection selection : selections) {
                                    if (image != null && image instanceof BufferedImage) {
                                        // 获取占位符所在的段落和位置
                                        TextRange range = selection.getAsOneRange();
                                        Paragraph paragraph = range.getOwnerParagraph();
                                        int index = paragraph.getChildObjects().indexOf(range);

                                        // 1. 移除占位符文本
                                        paragraph.getChildObjects().remove(range);

                                        // 2. 插入图片（Java版通过appendPicture创建DocPicture）
                                        DocPicture picture = paragraph.appendPicture((BufferedImage) image);
                                        picture.setWidth(size.width); // 设置宽度
                                        picture.setHeight(size.height); // 设置高度

                                        // 若需要调整图片位置（确保插入到原占位符位置）
                                        paragraph.getChildObjects().remove(picture); // 移除append的默认位置
                                        paragraph.getChildObjects().insert(index, picture); // 插入到原占位符位置
                                    } else {
                                        // 无图片时移除占位符
                                        TextRange range = selection.getAsOneRange();
                                        Paragraph paragraph = range.getOwnerParagraph();
                                        int index = paragraph.getChildObjects().indexOf(range);
                                        paragraph.getChildObjects().remove(range);
                                    }
                                }
                            } else if (dataColumn.contains("img1_")) {
                                TextSelection[] selections = document.findAllString(item, false, true);
                                for (TextSelection selection : selections) {
                                    TextRange range = selection.getAsOneRange();
                                    Paragraph paragraph = range.getOwnerParagraph();
                                    Object owner = paragraph.getOwnerTextBody().getOwner();
                                    if (owner instanceof TextBox) {
                                        TextBox textBox = (TextBox) owner;
                                        textBox.getFormat().getInternalMargin().setAll(0);
                                        Image image = InitCreatImage(columnValue, OAUrl);
                                        if (image == null) {
                                            image = Base64ToImage(columnValue);
                                        }
                                        Paragraph lastParagraph = GeObjectParagraph(document, textBox);
                                        if (image != null && lastParagraph != null) {
                                            // Java版需调整枚举类路径和方法名（setter）
                                            lastParagraph.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
                                            DocPicture picture = lastParagraph.appendPicture((BufferedImage) image);
                                            picture.setWidth((int) textBox.getWidth());
                                            picture.setHeight((int) textBox.getHeight());
                                            picture.setTextWrappingStyle(TextWrappingStyle.In_Front_Of_Text);
                                            picture.setTextWrappingType(TextWrappingType.Both);
                                            picture.setHorizontalPosition(textBox.getHorizontalPosition());
                                            picture.setVerticalPosition(textBox.getVerticalPosition());
                                            lastParagraph.getChildObjects().remove(textBox);
                                        }
                                        else if(lastParagraph != null){
                                            // Java版需调整枚举类路径和方法名（setter）
                                            lastParagraph.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
                                            lastParagraph.getChildObjects().remove(textBox);
                                        }
                                    }
                                }
                            }
                        }
                        else {
                            replaceTextRange(document, item, dataRow.get(dataColumn) + "",false,true);
                        }
                    }
                    else {
                        replaceTextRange(document, item, "",false,true);
                    }
                }
            }
        }
    }

    private static void InitCreatBaseSqlDetail(Document document, List<List<Map<String, Object>>> dataSet, String OAUrl){
        if (dataSet.size() < 2) {
            return;
        }
        List<Map<String, Object>> detailTab = dataSet.get(1);
        if (!detailTab.isEmpty() && detailTab.get(0).containsKey("crm_lco_xmbg")){
            // 分组去重：按"crm_lco_xmbg"分组，取每组第一个元素（对应C#的GroupBy+First）
            List<Map<String, Object>> distinctTable = detailTab.stream()
                    .collect(Collectors.groupingBy(row -> row.get("crm_lco_xmbg").toString()))
                    .values().stream()
                    .map(group -> group.get(0))
                    .collect(Collectors.toList());
            for (Map<String, Object> dataRow : distinctTable){
                String pargTag = dataRow.get("crm_lco_xmbg").toString();
                // 获取列名集合（对应C#的distinctTable.Columns）
                Set<String> columnNames = dataRow.keySet();
                for (String dataColumn : columnNames){
                    String speciesItem = "!{" + pargTag + "." + dataColumn + "}";
                    TextSelection[] speciesContains = document.findAllString(speciesItem, false, true);
                    if (speciesContains != null && speciesContains.length > 0) {
                        String cellValue = dataRow.get(dataColumn).toString();
                        if ("/".equals(cellValue)) {
                            replaceTextRange(document, speciesItem, "!/",false,true);
                            document.replace(speciesItem, "!/", false, true);
                        } else {
                            replaceTextRange(document, speciesItem, cellValue, false, true);
                            document.replace(speciesItem, cellValue, false, true);
                        }
                    }
                    String item = "{" + pargTag + "." + dataColumn + "}";
                    TextSelection[] contains = document.findAllString(item, false, true);
                    if (contains != null && contains.length > 0){
                        if(dataColumn.contains("img_")){
                            Image image = null;
                            Dimension size = new Dimension(200, 200);
                            String picUrl = dataRow.get(dataColumn).toString();
                            if(picUrl.startsWith("@") && jdbcTemplate != null){
                                List<Map<String,Object>> picTable = jdbcTemplate.queryForList(picUrl.substring(1));
                                if (picTable != null && picTable.size() > 0) {
                                    Map<String, Object> picRow = picTable.get(0);
                                    String path = picRow.containsKey("value") ? picRow.get("value").toString() : "";
                                    int width = 200;
                                    if (picRow.containsKey("width")) {
                                        try {
                                            width = Integer.parseInt(picRow.get("width").toString());
                                        } catch (NumberFormatException e) {
                                            width = 200;
                                        }
                                    }

                                    int height = 200;
                                    if (picRow.containsKey("height")) {
                                        try {
                                            height = Integer.parseInt(picRow.get("height").toString());
                                        } catch (NumberFormatException e) {
                                            height = 200;
                                        }
                                    }

                                    size = new Dimension(width, height);
                                    image = InitCreatImage(path, OAUrl);
                                }
                            }
                            else {
                                image = InitCreatImage(picUrl,OAUrl);
                                if(image == null){
                                    image = Base64ToImage(dataRow.get(dataColumn).toString());
                                }
                            }
                            TextSelection[] selections = document.findAllString(item, false, true);
                            for (TextSelection selection : selections) {
                                if (image != null) {
                                    TextRange range = selection.getAsOneRange();
                                    Paragraph paragraph = range.getOwnerParagraph();
                                    int index = paragraph.getChildObjects().indexOf(range);
                                    paragraph.getChildObjects().remove(range);
                                    DocPicture picture = paragraph.appendPicture((BufferedImage) image);
                                    picture.setWidth(size.width);
                                    picture.setHeight(size.height);
                                    paragraph.getChildObjects().remove(picture);
                                    paragraph.getChildObjects().insert(index, picture);
                                }
                            }
                        }
                        else if(dataColumn.contains("img1_")){
                            TextSelection[] selections = document.findAllString(item, false, true);
                            for (TextSelection selection : selections){
                                TextRange range = selection.getAsOneRange();
                                Paragraph paragraph = range.getOwnerParagraph();
                                Object owner = paragraph.getOwnerTextBody().getOwner();
                                if (owner instanceof TextBox) {
                                    TextBox textBox = (TextBox) owner;
                                    textBox.getFormat().getInternalMargin().setAll(0);
                                    Image image = InitCreatImage(dataRow.get(dataColumn).toString(), OAUrl);
                                    if (image == null) {
                                        image = Base64ToImage(dataRow.get(dataColumn).toString());
                                    }
                                    if (image != null){
                                        Paragraph lastParagraph = GeObjectParagraph(document, textBox);
                                        lastParagraph.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);

                                        DocPicture picture = lastParagraph.appendPicture((BufferedImage) image);
                                        picture.setWidth((int) textBox.getWidth());
                                        picture.setHeight((int) textBox.getHeight());
                                        picture.setTextWrappingStyle(TextWrappingStyle.In_Front_Of_Text);
                                        picture.setTextWrappingType(TextWrappingType.Both);
                                        picture.setHorizontalPosition(textBox.getHorizontalPosition());
                                        picture.setVerticalPosition(textBox.getVerticalPosition());

                                        lastParagraph.getChildObjects().remove(textBox);
                                    }
                                }
                            }
                        }
                        else {
                            replaceTextRange(document,item,dataRow.get(dataColumn).toString(),false,true);
                            document.replace(item, dataRow.get(dataColumn).toString(), false, true);
                        }
                    }
                }
            }
        }
    }

    private static void InitCreatTabSql(Document document, List<List<Map<String, Object>>> dataSet, String OAUrl){
        // Dictionary<Table, List<int>> → Java的Map<Table, List<Integer>>（HashMap实现）
        // word表格集合
        Map<Table, List<Integer>> disMergeDic = new HashMap<>();
        List<GridTarGet> targetTables = new ArrayList<>();
        // 正则表达式字符串（与C#一致，Java无需转义额外字符）
        String pattern = "^(?!L)\\{#data\\d+\\.(?!img_)\\w+}$"; // 匹配 {#data1.xxxxx}
        String pattern1 = "^(?!L)\\{!#data\\d+\\.(?!img_)\\w+}$"; // 匹配 {!#data1.xxxxx}
        // 遍历所有Section
        for (Object sectionObj : document.getSections()) {
            if (sectionObj instanceof Section) {
                Section section = (Section) sectionObj;

                // 遍历Section中的Table
                for (Object tableObj : section.getTables()) {
                    if (tableObj instanceof Table) {
                        Table table = (Table) tableObj;
                        // 检查第一行第一列的值是否符合模式
                        boolean isBreak = false;

                        // 遍历Table中的TableRow
                        for (Object rowObj : table.getRows()) {
//                            if (!(rowObj instanceof TableRow)) continue;
                            TableRow tableRow = (TableRow) rowObj;

                            // 遍历TableRow中的TableCell
                            for (Object cellObj : tableRow.getCells()){
//                                if (!(cellObj instanceof Cell)) continue;
                                TableCell tableCell = (TableCell) cellObj;
//                                int rowIndex = tableRow.getCells().indexOf(tableCell);
                                if(tableCell.getParagraphs().getCount() == 0){
                                    continue;
                                }
                                if (NativeExtensionUtils.isNullOrEmpty(tableCell.getParagraphs().get(0).getText())){
                                    continue;
                                }
                                boolean isMatch = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE)
                                        .matcher(tableCell.getParagraphs().get(0).getText()).find()
                                        || Pattern.compile(pattern1, Pattern.CASE_INSENSITIVE)
                                        .matcher(tableCell.getParagraphs().get(0).getText()).find();
                                if(isMatch){
                                    String npattern = "\\{!#data(\\d+)\\.\\w+\\}";
                                    Matcher nmatch = Pattern.compile(npattern, Pattern.CASE_INSENSITIVE).matcher(tableCell.getParagraphs().get(0).getText());
                                    if(nmatch.find()){
                                        if(disMergeDic.containsKey(table)){
                                            disMergeDic.get(table).add(tableRow.getCells().indexOf(tableCell));
                                        }
                                        else {
                                            List<Integer> cellIndexs = new ArrayList<>();
                                            cellIndexs.add(tableRow.getCells().indexOf(tableCell));
                                            disMergeDic.put(table,cellIndexs);
                                        }
                                        if (!isBreak) {
                                            GridTarGet gridTarGet = new GridTarGet();
                                            String patterner = "\\{#data(\\d+)\\.\\w+\\}";
                                            Pattern patterngrid = Pattern.compile(patterner, Pattern.CASE_INSENSITIVE);
                                            Matcher match = patterngrid.matcher(tableCell.getParagraphs().get(0).getText());

                                            if (match.find()) {
                                                gridTarGet.setNumber(match.group(1)); // 提取捕获组1的数字
                                            }

                                            gridTarGet.setTargetSection(section) ;
                                            gridTarGet.setTargetTable(table) ;
                                            gridTarGet.setRowIndex(tableRow.getRowIndex()) ;
                                            targetTables.add(gridTarGet);
                                            isBreak = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        for (GridTarGet gridTar : targetTables){
            try{
                if (dataSet.size() < Integer.parseInt(gridTar.number)) {
                    break; // 若在循环中，可终止循环
                }
                // 获取对应的数据表（模拟DataSet）
                List<Map<String, Object>> dataTable = dataSet.get(Integer.parseInt(gridTar.number) - 1);
                Section section = gridTar.getTargetSection();
                Table table = gridTar.getTargetTable();
                // 从表格指定行获取列名（提取{#dataX.xxx}中的xxx）
                List<String> columnNames = new ArrayList<>();
                for (Object objcell : table.getRows().get(gridTar.rowIndex).getCells()){
                    if (objcell instanceof TableCell){
                        TableCell cell = (TableCell) objcell;
                        if(cell.getParagraphs().getCount() == 0){continue;}
                        Matcher match = Pattern.compile("\\{#data\\d+\\.(\\w+)\\}", Pattern.CASE_INSENSITIVE).matcher(cell.getParagraphs().get(0).getText());
                        if(match.find()){
                            columnNames.add(match.group(1));
                        }
                    }
                }
                for (int i = 0; i < dataTable.size(); i++) {
                    Map<String, Object> dataRow = dataTable.get(i); // 模拟DataRow
                    // 克隆模板行并插入表格（对应C#的Clone+Insert）
                    TableRow newRow = (TableRow)table.getRows().get(gridTar.rowIndex).deepClone();
                    table.getRows().insert(gridTar.rowIndex + i + 1, newRow);

                    for(int j = 0; j < columnNames.size(); j++){
                        if (dataRow.containsKey(columnNames.get(j))){
                            // 获取列名，并从数据行中获取相应的数据
                            Paragraph cloneParagraph = (Paragraph)table.getRows().get(gridTar.rowIndex).getCells().get(j).getParagraphs().get(0).deepClone();
                            CharacterFormat characterFormat = null;
                            if (cloneParagraph.getChildObjects().get(0) instanceof TextRange) {
                                characterFormat = ((TextRange)cloneParagraph.getChildObjects().get(0)).getCharacterFormat();
                            }
                            ParagraphFormat paragraphFormat = newRow.getCells().get(j).getParagraphs().get(0).getFormat();
                            newRow.getCells().get(j).getParagraphs().clear();
                            newRow.getCells().get(j).getParagraphs().add(cloneParagraph);
                            String text = dataRow.get(columnNames.get(j)) + "";
                            String[] result = Pattern.compile("\\r\\n|\\r|\\n").split(text);
                            cloneParagraph.setText("");
                            for (int k = 0 ; k < result.length; k++){
                                String resultText = result[k];
                                if(k > 0){
                                    Break lineBreak = new Break(document, BreakType.Line_Break);
                                    cloneParagraph.getChildObjects().add(lineBreak);
                                }
                                TextRange textRange = cloneParagraph.appendText(resultText);
                                textRange.applyCharacterFormat(characterFormat);
                            }
                            cloneParagraph.getFormat().setTextAlignment(paragraphFormat.getTextAlignment());
                            cloneParagraph.getFormat().setHorizontalAlignment(paragraphFormat.getHorizontalAlignment());
                        }
                    }
                }
                if (dataTable.size() > 0) {
                    table.getRows().remove(table.getRows().get(gridTar.rowIndex));
                }
                MergeTable(disMergeDic,table,gridTar.rowIndex,gridTar.rowIndex + dataTable.size() - 1 ,table.getRows().get(gridTar.rowIndex).getCells().getCount());
            } catch (NumberFormatException e) {
                throw new RuntimeException(e);
            }
        }
        // 表格图片集合
        List<GridTarGet> pictureTables = new ArrayList<>();
        String imgpattern = "^(?!L)\\{#data\\d+\\.img_\\w+}$";
        for (Object sectionobj : document.getSections()){
            if (sectionobj instanceof Section){
                Section section = (Section) sectionobj;

                for (Object tableobj : section.getTables()){
                    Table table = (Table) tableobj;
                    boolean isImgBreak = false;

                    for (Object tableRowobj : table.getRows()){
                        TableRow tableRow = (TableRow) tableRowobj;

                        for (Object cellobj : tableRow.getCells()){
                            TableCell tableCell = (TableCell) cellobj;

                            if (tableCell.getParagraphs().getCount() == 0){continue;}
                            String cellText = tableCell.getParagraphs().get(0).getText();
                            if (Pattern.compile(imgpattern, Pattern.CASE_INSENSITIVE).matcher(cellText).matches()){
                                if (!isImgBreak){
                                    GridTarGet gridTarGet = new GridTarGet();
                                    String patterner = "\\{#data(\\d+)\\.img_\\w+\\}";
                                    Matcher match = Pattern.compile(patterner, Pattern.CASE_INSENSITIVE).matcher(cellText);
                                    if (match.find()) {
                                        gridTarGet.setNumber(match.group(1)); // 捕获组的索引
                                    }
                                    gridTarGet.setTargetSection(section);
                                    gridTarGet.setTargetTable(table);
                                    gridTarGet.setRowIndex(tableRow.getRowIndex());
                                    pictureTables.add(gridTarGet); // 添加到集合中
                                    isImgBreak = true;
                                }
                            }
                        }
                    }
                }
            }
        }
        for (GridTarGet gridTar : pictureTables){
            try {
                if (dataSet.size() < Integer.parseInt(gridTar.number)) { // 替换C#的dataSet.Tables.Count → Java模拟DataSet的size()
                    break; // 与C#的break逻辑一致
                }
            }
            catch (NumberFormatException e) {
            }
            List<Map<String, Object>> dataTable = dataSet.get(Integer.parseInt(gridTar.number) - 1);
            Section section = gridTar.targetSection;
            Table table = gridTar.targetTable;
            List<String> columnNames = new ArrayList<>();
            for (Object objcell : table.getRows().get(gridTar.rowIndex).getCells()){
                if (objcell instanceof TableCell){
                    TableCell cell = (TableCell) objcell;
                    if(cell.getParagraphs().getCount() == 0){continue;}
                    Matcher match = Pattern.compile("\\{#data\\d+\\.(img_\\w+)\\}", Pattern.CASE_INSENSITIVE)
                            .matcher(cell.getParagraphs().get(0).getText());
                    if(match.find()){
                        columnNames.add(match.group(1));
                    }
                }
            }
            if(dataTable.size() > 0){
                String picUrl = (!dataTable.isEmpty() && dataTable.get(0).containsKey(columnNames.get(0) + ""))
                        ? (dataTable.get(0).get(columnNames.get(0)) + "")
                        : "";
                if (!isNullOrEmpty(picUrl)){
                    List<String> picNameArray = new ArrayList<>();
                    List<String> picUrlArray = new ArrayList<>();
                    List<Dimension> picSizeArray = new ArrayList<>();
                    if(picUrl.startsWith("@") && jdbcTemplate!= null ){
                        List<Map<String,Object>> picTable = jdbcTemplate.queryForList(picUrl.substring(1));
                        if(picTable != null){
                            for (Map<String, Object> item : picTable){
                                try{
                                    // 对应C#的name获取逻辑（含列存在性判断+文件名处理）
                                    String name = item.containsKey("name")
                                            ? FilenameUtils.getBaseName(item.get("name").toString())
                                            : "";
                                    // 对应C#的path获取逻辑
                                    String path = item.containsKey("value")
                                            ? item.get("value").toString()
                                            : "";
                                    int width = 200; // 默认值
                                    if (item.containsKey("width")) {
                                        try {
                                            width = Integer.parseInt(item.get("width").toString());
                                        } catch (NumberFormatException e) {
                                            width = 200; // 解析失败则用默认值
                                        }
                                    }
                                    int height = 200; // 默认值
                                    if (item.containsKey("height")) {
                                        try {
                                            height = Integer.parseInt(item.get("height").toString());
                                        } catch (NumberFormatException e) {
                                            height = 200; // 解析失败则用默认值
                                        }
                                    }
                                    Dimension size = new Dimension(width, height);
                                    picNameArray.add(name);
                                    picUrlArray.add(path);
                                    picSizeArray.add(size);
                                } catch (Exception e) {
                                    log.debug(String.valueOf(e.getMessage()));
                                }
                            }
                        }
                    }
                    else {
                        picUrlArray = new ArrayList<>(Arrays.asList(TrimEnd(picUrl, ',').split(",")));
                    }
                    int rowsCount = picUrlArray.size();
                    TableRow addRow = null;
                    List<Image> addImages = new ArrayList<>();
                    List<TableRow> addRows = new ArrayList<>();
                    List<TableRow> afterAddRows = new ArrayList<>();
                    for (int i = 0; i < table.getRows().getCount(); i++){
                        if (i >= gridTar.getRowIndex()){
                            addRows.add(table.getRows().get(i));
                        }
                    }
                    for (int i = 1; i <= rowsCount; i++){
                        Image image = null;
                        String imageUrl = picUrlArray.size() > 0 ? picUrlArray.get(i - 1) : "";
                        String imageName = picNameArray.size() > 0 ? picNameArray.get(i - 1) : "";
                        Dimension imageSize = picSizeArray.size() > 0 ? picSizeArray.get(i - 1) : new Dimension(200, 200);
                        image = InitCreatImage(imageUrl, OAUrl);
                        if(image == null){
                            image = Base64ToImage(picUrlArray.get(i-1));
                        }
                        if (image == null){continue;}
                        if (i%2 == 1){
                            afterAddRows = new ArrayList<>();
                            for (TableRow item : addRows){
                                int Inde = addRows.indexOf(item);
                                TableRow newRow = item.deepClone();
                                float totalWidth = 0f;
                                for (Object cellobj : newRow.getCells()){
                                    if (cellobj instanceof TableCell){
                                        TableCell cell = (TableCell) cellobj;
                                        totalWidth += cell.getCellWidth();
                                    }
                                }
                                TableCell newCell1 = new TableCell(document);
                                TableCell newCell2 = new TableCell(document);
                                // 设置单元格宽度为原行宽度的一半
                                newCell1.setCellWidth(50,CellWidthType.Percentage);
                                newCell1.getCellFormat().setBackColor(item.getCells().get(0).getCellFormat().getBackColor());
                                newCell1.getCellFormat().setVerticalAlignment(item.getCells().get(0).getCellFormat().getVerticalAlignment());

                                newCell2.setCellWidth(50,CellWidthType.Percentage);
                                newCell2.getCellFormat().setBackColor(item.getCells().get(0).getCellFormat().getBackColor());
                                newCell2.getCellFormat().setVerticalAlignment(item.getCells().get(0).getCellFormat().getVerticalAlignment());

                                // 将两个新的单元格添加到行中
                                newRow.getCells().clear();
                                newRow.getCells().add(newCell1);
                                newRow.getCells().add(newCell2);
                                table.getRows().add(newRow);
                                afterAddRows.add(newRow);
                            }
                            for (TableRow item : afterAddRows){
                                int addRowIndex = afterAddRows.indexOf(item);
                                TableRow beforeRow = addRows.get(addRowIndex);
                                TableRow newRow = item;
                                int nowIndex = table.getRows().indexOf(item);
                                if (i%2 == 1){
                                    if (addRowIndex == 0){
                                        Paragraph paragraph = newRow.getCells().get(0).addParagraph();
                                        paragraph.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
                                        DocPicture picture = paragraph.appendPicture((BufferedImage) image);
                                        picture.setHorizontalAlignment(ShapeHorizontalAlignment.Center);
                                        picture.setVerticalAlignment(ShapeVerticalAlignment.Center);
                                        picture.setWidth((float) imageSize.getWidth());
                                        picture.setHeight((float) imageSize.getHeight());

                                    } else if (addRowIndex > 0) {
                                        for (Object paragraphItemobj : beforeRow.getCells().get(0).getParagraphs()){
                                            if (paragraphItemobj instanceof Paragraph){
                                                Paragraph paragraphItem = (Paragraph) paragraphItemobj;
                                                Paragraph newParagraph = (Paragraph) paragraphItem.deepClone();
                                                if (!isNullOrEmpty(imageName)){
                                                    newParagraph.setText(imageName);
                                                }
                                                newRow.getCells().get(0).getParagraphs().add(newParagraph);
                                            }
                                        }
                                    }
                                }
                                if(i == rowsCount){
                                    table.applyHorizontalMerge(nowIndex, 0, newRow.getCells().getCount() - 1);
                                }
                            }
                        } else if (i%2 == 0 && afterAddRows != null) {
                            for (TableRow item : afterAddRows){
                                int addRowIndex = afterAddRows.indexOf(item);
                                TableRow beforeRow = addRows.get(addRowIndex);
                                TableRow newRow = item;
                                if (image != null && addRowIndex == 0){
                                    Paragraph paragraph = newRow.getCells().get(0).addParagraph();
                                    paragraph.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
                                    DocPicture picture = paragraph.appendPicture((BufferedImage) image);
                                    picture.setHorizontalAlignment(ShapeHorizontalAlignment.Center);
                                    picture.setVerticalAlignment(ShapeVerticalAlignment.Center);
                                    picture.setWidth((float) imageSize.getWidth());
                                    picture.setHeight((float) imageSize.getHeight());
                                } else if (addRowIndex > 0) {
                                    for (Object paragraphItemobj : beforeRow.getCells().get(0).getParagraphs()){
                                        if (paragraphItemobj instanceof Paragraph){
                                            Paragraph paragraphItem = (Paragraph) paragraphItemobj;
                                            Paragraph newParagraph = (Paragraph)paragraphItem.deepClone();
                                            if (!isNullOrEmpty(imageName))
                                            {
                                                newParagraph.setText(imageName);
                                            }
                                            newRow.getCells().get(1).getParagraphs().add(newParagraph);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    for (int i = 1; i <= addRows.size(); i++){
                        table.getRows().remove(table.getRows().get(0));
                    }
                }
                else {
                    section.getBody().getChildObjects().remove(table);
                }
                String l_imgpattern = "\\{L#data(\\d+)\\.\\w+}";
                for (Object tableRowobj : table.getRows()){
                    if (tableRowobj instanceof TableRow){
                        TableRow tableRow = (TableRow) tableRowobj;

                        for (Object cellobj : tableRow.getCells()){
                            if (cellobj instanceof TableCell){
                                TableCell tableCell = (TableCell) cellobj;
                                if (tableCell.getParagraphs().getCount() == 0){continue;}
                                String cellText = tableCell.getParagraphs().get(0).getText();
                                if (Pattern.compile(l_imgpattern, Pattern.CASE_INSENSITIVE).matcher(cellText).find()){
                                    GridTarGet sourceGridTarGet = new GridTarGet();
                                    Matcher match = Pattern.compile(l_imgpattern, Pattern.CASE_INSENSITIVE).matcher(cellText);
                                    if (match.find()){
                                        sourceGridTarGet.number = match.group(1);
                                    }
                                    sourceGridTarGet.setTargetTable(table);
                                    sourceGridTarGet.setRowIndex(tableRow.getRowIndex());
                                    try {
                                        if (dataSet.size() < Integer.parseInt(sourceGridTarGet.number)) {
                                            break;
                                        }
                                    } catch (NumberFormatException ignored) {}
                                    // 当前表需要用到的数据源
                                    List<Map<String, Object>> sourceTable = dataSet.get(Integer.parseInt(sourceGridTarGet.number) - 1);
                                    for (Map<String, Object> dataColumn : sourceTable){
                                        String lastColumn = "{L#Data" + sourceGridTarGet.number + "." + dataColumn + "}";
                                        TextSelection[] selections = document.findAllString(lastColumn, false, true);
                                        if (selections != null && selections.length > 0) {
                                            String value = "";
                                            if (sourceTable.size() > 0) {
                                                Map<String, Object> lastRow = sourceTable.get(sourceTable.size() - 1);
                                                Object columnValue = lastRow.get(dataColumn);
                                                value = columnValue != null ? columnValue.toString() : "";
                                            }
                                            replaceTextRange(document,lastColumn, value, false, true);
                                            document.replace(lastColumn, value, false, true);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }


    private static void InitCreatTabSqlDetail(Document document, List<List<Map<String, Object>>> dataSet, String OAUrl) {
        if (dataSet.size() < 2){ return;}
        List<Map<String, Object>> detailTab = dataSet.get(1);
        Map<Table, List<Integer>> disMergeDic = new HashMap<>();
        List<GridTarGet> targetTables = new ArrayList<>();
        String pattern = "^(?!L)\\{#\\w+\\.(?!img_)\\w+}$";
        String pattern1 = "^(?!L)\\{!#\\w+\\.(?!img_)\\w+}$";
        for (Object sectionobj : document.getSections()){
            if (sectionobj instanceof Section){
                Section section = (Section) sectionobj;

                for (Object tableobj : section.getTables()){
                    if (tableobj instanceof Table){
                        Table table = (Table) tableobj;
                        boolean isBreak = false;
                        for (Object tableRowobj : table.getRows()){
                            if (tableRowobj instanceof TableRow){
                                TableRow tableRow = (TableRow) tableRowobj;

                                for (Object cellobj : tableRow.getCells()){
                                    if (cellobj instanceof TableCell){
                                        TableCell tableCell = (TableCell) cellobj;
                                        if (tableCell.getParagraphs().getCount() == 0){
                                            continue;
                                        }
                                        if (isNullOrEmpty(tableCell.getParagraphs().get(0).getText())){
                                            continue;
                                        }
                                        if (Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(tableCell.getParagraphs().get(0).getText()).find() || Pattern.compile(pattern1, Pattern.CASE_INSENSITIVE).matcher(tableCell.getParagraphs().get(0).getText()).find()){
                                            String npattern = "\\{!#\\w+\\.\\w+\\}";
                                            Matcher nmatch = Pattern.compile(npattern, Pattern.CASE_INSENSITIVE).matcher(tableCell.getParagraphs().get(0).getText());
                                            if (nmatch.find()) {
                                                if (disMergeDic.containsKey(table)) {
                                                    disMergeDic.get(table).add(tableRow.getCells().indexOf(tableCell));
                                                }
                                                else {
                                                    List<Integer> cellIndexList = new ArrayList<>();
                                                    cellIndexList.add(tableRow.getCells().indexOf(tableCell));
                                                    disMergeDic.put(table, cellIndexList);
                                                }
                                                String originalText = tableCell.getParagraphs().get(0).getText();
                                                tableCell.getParagraphs().get(0).setText(originalText.replace("!#", "#"));
                                            }
                                            if (!isBreak){
                                                GridTarGet gridTarGet = new GridTarGet();
                                                String patterner = "\\{#(\\w+)\\.\\w+\\}";
                                                Matcher match = Pattern.compile(patterner, Pattern.CASE_INSENSITIVE).matcher(tableCell.getParagraphs().get(0).getText());
                                                if (match.find()) {
                                                    gridTarGet.setNumber(match.group(1)); // 捕获组的索引
                                                }
                                                gridTarGet.setTargetTable(table);
                                                gridTarGet.setRowIndex(tableRow.getRowIndex());
                                                targetTables.add(gridTarGet); // 添加到集合中
                                                isBreak = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        for (GridTarGet gridTar : targetTables){
            try{
//                Clone,似乎只克隆结构,不克隆数据
                List<Map<String, Object>> dataTable = new ArrayList<>();
                detailTab.stream().filter(map -> gridTar.number.equals((map.get("crm_lco_xmbg") + ""))).forEach(dataTable::add);
                Table table = gridTar.getTargetTable();
                List<String> columnNames = new ArrayList<>();
                for (Object cellobj : table.getRows().get(gridTar.rowIndex).getCells()){
                    if (cellobj instanceof TableCell){
                        TableCell cell = (TableCell) cellobj;
                        if (cell.getParagraphs().getCount() == 0){
                            continue;
                        }
                        Matcher match = Pattern.compile("\\{#\\w+\\.(\\w+)\\}", Pattern.CASE_INSENSITIVE).matcher(cell.getParagraphs().get(0).getText());
                        if (match.find()) {
                            columnNames.add(String.format("{%s}", match.group(1))); // 添加匹配到的xxxxx部分到集合中
                        } else {
                            columnNames.add(cell.getParagraphs().get(0).getText());
                        }
                    }
                }
                for (int i = 0; i < dataTable.size(); i++){
                    Map<String, Object> dataRow = dataTable.get(i);
                    TableRow newRow = table.getRows().get(gridTar.rowIndex).deepClone();
                    table.getRows().insert(gridTar.rowIndex + i + 1, newRow);
                    for(int j = 0; j < columnNames.size(); j++){
                        String columnName = columnNames.get(j);
                        Paragraph cloneParagraph = (Paragraph) table.getRows().get(gridTar.rowIndex).getCells().get(j).getParagraphs().get(0).deepClone();
                        CharacterFormat characterFormat = ((TextRange) cloneParagraph.getChildObjects().get(0)).getCharacterFormat();
                        ParagraphFormat paragraphFormat = newRow.getCells().get(j).getParagraphs().get(0).getFormat();
                        newRow.getCells().get(j).getParagraphs().clear();
                        newRow.getCells().get(j).getParagraphs().add(cloneParagraph);
                        if (columnName.startsWith("{") && columnName.endsWith("}")){
                            columnName = columnName.replaceAll("^\\{", "").replaceAll("\\}$", "");
                            if (columnNames.contains(columnName)){
                                String text = dataRow.get(columnName) + "";
                                String splitPattern = "\\r\\n|\\r|\\n"; // 匹配 CRLF (\r\n), CR (\r), LF (\n)
                                String[] result = Pattern.compile(splitPattern).split(text);
                                cloneParagraph.setText("");
                                for (int k = 0; k < result.length; k++) {
                                    String resultText = result[k];
                                    if (k > 0) {
                                        Break lineBreak = new Break(document, BreakType.Line_Break);
                                        cloneParagraph.getChildObjects().add(lineBreak);
                                    }
                                    TextRange textRange = cloneParagraph.appendText(resultText);
                                    textRange.applyCharacterFormat(characterFormat);
                                }
                            }
                        }
                        else {
                            cloneParagraph.setText(columnName);
                        }
                        cloneParagraph.getFormat().setTextAlignment(paragraphFormat.getTextAlignment());
                        cloneParagraph.getFormat().setHorizontalAlignment(paragraphFormat.getHorizontalAlignment());
                    }
                }
                if (dataTable.size() > 0){
                    table.getRows().remove(table.getRows().get(gridTar.rowIndex));
                }
                MergeTable(disMergeDic,table,gridTar.rowIndex,gridTar.rowIndex + dataTable.size() -1, table.getRows().get(gridTar.rowIndex).getCells().getCount());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        List<GridTarGet> pictrueTables = new ArrayList<>();
        String imgpattern = "^(?!L)\\{#\\w+\\.img_\\w+\\}$";
        for (Object sectionobj : document.getSections()){
            if (sectionobj instanceof Section){
                Section section = (Section) sectionobj;

                for (Object tableobj : section.getTables()){
                    if (tableobj instanceof Table){
                        Table table = (Table) tableobj;
                        boolean isImgBreak = false;

                        for (Object tableRowobj : table.getRows()){
                            if (tableRowobj instanceof TableRow){
                                TableRow tableRow = (TableRow) tableRowobj;

                                for (Object tableCellobj : tableRow.getCells()){
                                    if (tableCellobj instanceof TableCell){
                                        TableCell tableCell = (TableCell) tableCellobj;
                                        if (tableCell.getParagraphs().getCount() == 0){
                                            continue;
                                        }
                                        String cellText = tableCell.getParagraphs().get(0).getText();
                                        if (Pattern.compile(imgpattern, Pattern.CASE_INSENSITIVE).matcher(cellText).find()) {
                                            if (!isImgBreak) {
                                                GridTarGet gridTarGet = new GridTarGet();
                                                String patterner = "\\{#(\\w+)\\.img_\\w+\\}";
                                                Matcher match = Pattern.compile(patterner, Pattern.CASE_INSENSITIVE).matcher(cellText);
                                                if (match.find()) {
                                                    gridTarGet.number = match.group(1); // 捕获组的索引
                                                }
                                                gridTarGet.targetSection = section;
                                                gridTarGet.targetTable = table;
                                                gridTarGet.rowIndex = tableRow.getRowIndex();
                                                pictrueTables.add(gridTarGet); // 添加到集合中
                                                isImgBreak = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        };
        for (GridTarGet gridTar : pictrueTables){
            List<Map<String, Object>> dataTable = new ArrayList<>();
            detailTab.stream().filter(map -> gridTar.getNumber().equals((map.get("crm_lco_xmbg") + ""))).forEach(dataTable::add);
            Table table = gridTar.getTargetTable();
            Section section = gridTar.getTargetSection();
            List<String> columnNames = new ArrayList<>();
            for (Object cellobj : table.getRows().get(gridTar.rowIndex).getCells()){
                if (cellobj instanceof TableCell){
                    TableCell cell = (TableCell) cellobj;
                    if (cell.getParagraphs().getCount() == 0){
                        continue;
                    }
                    Matcher match = Pattern.compile("\\{#\\w+\\.(img_\\w+)\\}", Pattern.CASE_INSENSITIVE).matcher(cell.getParagraphs().get(0).getText());
                    if (match.find()) {
                        columnNames.add(match.group(1)); // 添加匹配到的xxxxx部分到集合中
                    }
                }
            }
            if (dataTable.size() > 0){
                String picUrl = (!dataTable.isEmpty() && dataTable.get(0).containsKey(columnNames.get(0) + "")) ? (dataTable.get(0).get(columnNames.get(0) + "") + "") : "";
                if (!picUrl.trim().isEmpty()){
                    List<String> picNameArray = new ArrayList<>();
                    List<String> picUrlArray = new ArrayList<>();
                    List<Dimension> picSizeArray = new ArrayList<>();
                    if (picUrl.startsWith("@") && jdbcTemplate!= null){
                        List<Map<String, Object>> picTable = jdbcTemplate.queryForList(picUrl.substring(1));
                        if (picTable !=  null){
                            for (Map<String, Object> item : picTable){
                                try{
                                    String name = item.containsKey("name") ? FilenameUtils.getBaseName(item.get("name") + "") : "";
                                    String path = item.containsKey("value") ? (item.get("value") + "") : "";

                                    int width = 200;
                                    if (item.containsKey("width")) {
                                        try {
                                            width = Integer.parseInt(item.get("width") + "");
                                        } catch (NumberFormatException e) {
                                            width = 200;
                                        }
                                    }

                                    int height = 200;
                                    if (item.containsKey("height")) {
                                        try {
                                            height = Integer.parseInt(item.get("height") + "");
                                        } catch (NumberFormatException e) {
                                            height = 200;
                                        }
                                    }

                                    Dimension size = new Dimension(width, height);
                                    picNameArray.add(name);
                                    picUrlArray.add(path);
                                    picSizeArray.add(size);

                                } catch (Exception e) {
                                    log.debug(String.valueOf(e.getMessage()));
                                }
                            }
                        }
                    }
                    else {
                        picUrlArray = new ArrayList<>(Arrays.asList(TrimEnd(picUrl, ',').split(",")));
                    }
                    int rowsCount = picUrlArray.size();
                    TableRow addRow = null;
                    List<Image> addImages = new ArrayList<>();
                    List<TableRow> addRows = new ArrayList<>();
                    List<TableRow> afterAddRows = new ArrayList<>();
                    for (int i = 0; i < table.getRows().getCount(); i++) {
                        if (i >= gridTar.rowIndex)
                        {
                            addRows.add(table.getRows().get(i));
                        }
                    }
                    for (int i = 1; i <= rowsCount; i++) {
                        Image image = null;
                        String imageUrl = picUrlArray.size() > 0 ? picUrlArray.get(i - 1) : "";
                        String imageName = picNameArray.size() > 0 ? picNameArray.get(i - 1) : "";
                        Dimension imageSize = picSizeArray.size() > 0 ? picSizeArray.get(i - 1) : new Dimension(200, 200);
                        image = InitCreatImage(imageUrl, OAUrl);

                        if (image == null){image = Base64ToImage(picUrlArray.get(i-1));};
                        if (image == null){continue;};
                        if (i % 2 == 1){
                            afterAddRows = new ArrayList<>();
                            for (TableRow item : addRows){
                                    int Inde = addRows.indexOf(item);
                                    TableRow newRow = item.deepClone();
                                    float totalWidth = 0f;
                                    for (Object cellobj : newRow.getCells()){
                                        if (cellobj instanceof TableCell){
                                            TableCell cell = (TableCell) cellobj;
                                            totalWidth += cell.getCellWidth();
                                        }
                                    }
                                    TableCell newCell1 = new TableCell(document);
                                    TableCell newCell2 = new TableCell(document);
                                    // 设置单元格宽度为原行宽度的一半
                                    newCell1.setCellWidth(50,CellWidthType.Percentage);
                                    newCell1.getCellFormat().setBackColor(item.getCells().get(0).getCellFormat().getBackColor());
                                    newCell1.getCellFormat().setVerticalAlignment(item.getCells().get(0).getCellFormat().getVerticalAlignment());

                                    newCell2.setCellWidth(50,CellWidthType.Percentage);
                                    newCell2.getCellFormat().setBackColor(item.getCells().get(0).getCellFormat().getBackColor());
                                    newCell2.getCellFormat().setVerticalAlignment(item.getCells().get(0).getCellFormat().getVerticalAlignment());

                                    // 将两个新的单元格添加到行中
                                    newRow.getCells().clear();
                                    newRow.getCells().add(newCell1);
                                    newRow.getCells().add(newCell2);
                                    table.getRows().add(newRow);
                                    afterAddRows.add(newRow);
                            }
                            for(TableRow item : afterAddRows){
                                int addRowIndex = afterAddRows.indexOf(item);
                                TableRow beforeRow = addRows.get(addRowIndex);
                                TableRow newRow = item;
                                int nowIndex = table.getRows().indexOf(item);
                                if (i%2 == 1){
                                    if (addRowIndex == 0){
                                        Paragraph paragraph = newRow.getCells().get(0).addParagraph();
                                        paragraph.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
                                        DocPicture picture = paragraph.appendPicture((BufferedImage) image);
                                        picture.setHorizontalAlignment(ShapeHorizontalAlignment.Center);
                                        picture.setVerticalAlignment(ShapeVerticalAlignment.Center);
                                        picture.setWidth((float) imageSize.getWidth());
                                        picture.setHeight((float) imageSize.getHeight());

                                    }
                                    else if (addRowIndex > 0) {
                                        for (Object paragraphItemobj : beforeRow.getCells().get(0).getParagraphs()){
                                            if (paragraphItemobj instanceof Paragraph){
                                                Paragraph paragraphItem = (Paragraph) paragraphItemobj;
                                                Paragraph newParagraph = (Paragraph) paragraphItem.deepClone();
                                                if (!isNullOrEmpty(imageName)){
                                                    newParagraph.setText(imageName);
                                                }
                                                newRow.getCells().get(0).getParagraphs().add(newParagraph);
                                            }
                                        }
                                    }
                                }
                                if(i == rowsCount){
                                    table.applyHorizontalMerge(nowIndex,0,newRow.getCells().getCount() - 1);
                                }
                            }
                        }
                        else if (i%2 == 0 && afterAddRows != null) {
                            for (TableRow item : afterAddRows){
                                int addRowIndex = afterAddRows.indexOf(item);
                                TableRow beforeRow = addRows.get(addRowIndex);
                                TableRow newRow = item;
                                if (image != null && addRowIndex == 0){
                                    Paragraph paragraph = newRow.getCells().get(0).addParagraph();
                                    paragraph.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
                                    DocPicture picture = paragraph.appendPicture((BufferedImage) image);
                                    picture.setHorizontalAlignment(ShapeHorizontalAlignment.Center);
                                    picture.setVerticalAlignment(ShapeVerticalAlignment.Center);
                                    picture.setWidth((float) imageSize.getWidth());
                                    picture.setHeight((float) imageSize.getHeight());
                                } else if (addRowIndex > 0) {
                                    for (Object paragraphItemobj : beforeRow.getCells().get(0).getParagraphs()){
                                        if (paragraphItemobj instanceof Paragraph){
                                            Paragraph paragraphItem = (Paragraph) paragraphItemobj;
                                            Paragraph newParagraph = (Paragraph)paragraphItem.deepClone();
                                            if (!isNullOrEmpty(imageName))
                                            {
                                                newParagraph.setText(imageName);
                                            }
                                            newRow.getCells().get(1).getParagraphs().add(newParagraph);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    for (int i = 0; i < addRows.size(); i++)
                    {
                        table.getRows().remove(table.getRows().get(0));
                    }
                }
                else {
                    section.getBody().getChildObjects().remove(table);
                }
                String l_imgpattern = "\\{L#(\\w+)\\.\\w+}";
                for (Object tableRowobj : table.getRows()){
                    if (tableRowobj instanceof TableRow){
                        TableRow tableRow = (TableRow) tableRowobj;

                        for (Object cellobj : tableRow.getCells()){
                            if (cellobj instanceof TableCell){
                                TableCell tableCell = (TableCell) cellobj;
                                if (tableCell.getParagraphs().getCount() == 0){continue;}
                                String cellText = tableCell.getParagraphs().get(0).getText();
                                if (Pattern.compile(l_imgpattern, Pattern.CASE_INSENSITIVE).matcher(cellText).find()){
                                    GridTarGet sourceGridTarGet = new GridTarGet();
                                    Matcher match = Pattern.compile(l_imgpattern, Pattern.CASE_INSENSITIVE).matcher(cellText);
                                    if (match.find()){
                                        sourceGridTarGet.number = match.group(1);
                                    }
                                    sourceGridTarGet.setTargetTable(table);
                                    sourceGridTarGet.setRowIndex(tableRow.getRowIndex());
                                    try {
                                        if (dataSet.size() < Integer.parseInt(sourceGridTarGet.number)) {
                                            break;
                                        }
                                    } catch (NumberFormatException ignored) {}
                                    // 当前表需要用到的数据源
                                    List<Map<String, Object>> sourceTable = dataSet.get(Integer.parseInt(sourceGridTarGet.number) - 1);
                                    for (Map<String, Object> dataColumn : sourceTable){
                                        String lastColumn = "{L#Data" + sourceGridTarGet.number + "." + dataColumn + "}";
                                        TextSelection[] selections = document.findAllString(lastColumn, false, true);
                                        if (selections != null && selections.length > 0) {
                                            String value = "";
                                            if (sourceTable.size() > 0) {
                                                Map<String, Object> lastRow = sourceTable.get(sourceTable.size() - 1);
                                                Object columnValue = lastRow.get(dataColumn);
                                                value = columnValue != null ? columnValue.toString() : "";
                                            }
                                            replaceTextRange(document,lastColumn, value, false, true);
                                            document.replace(lastColumn, value, false, true);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
;    }

    private static void RemoveTableRow(Document document){
        // 遍历文档中的所有Section（非泛型集合需类型转换）
        for (Object sectionObj : document.getSections()) {
            if (sectionObj instanceof Section) {
                Section section = (Section) sectionObj;

                // 遍历Section中的所有Table
                for (Object tableObj : section.getTables()) {
                    if (tableObj instanceof Table) {
                        Table table = (Table) tableObj;
                        List<TableRow> deleteRows = new ArrayList<>();

                        // 遍历Table中的所有TableRow
                        for (Object rowObj : table.getRows()) {
                            if (rowObj instanceof TableRow) {
                                TableRow tableRow = (TableRow) rowObj;

                                // 遍历TableRow中的所有TableCell
                                for (Object cellObj : tableRow.getCells()) {
                                    if (cellObj instanceof TableCell) {
                                        TableCell tableCell = (TableCell) cellObj;

                                        // 判断单元格是否有段落
                                        if (tableCell.getParagraphs().getCount() == 0) {
                                            continue;
                                        }

                                        // 获取单元格第一段文本
                                        String cellText = tableCell.getParagraphs().get(0).getText();
                                        if ("!/".equals(cellText)) {
                                            deleteRows.add(tableRow);
                                            break; // 找到匹配行，跳出单元格循环
                                        }
                                    }
                                }
                            }
                        }

                        // 删除标记的行
                        for (TableRow tableRow : deleteRows) {
                            table.getRows().remove(tableRow);
                        }
                    }
                }
            }
        }
    }


    //    辅助方法
    private static void CpoyHeaderFooter(Section sourceSection, Section targetSection, HeaderFooterType headerFooterType) {
        // 修正：通过枚举索引获取页眉/页脚（Java版HeadersFooters用索引访问）
        HeaderFooter headerFooter = sourceSection.getHeadersFooters().get(headerFooterType.ordinal());
        // 判断页眉/页脚是否存在且有内容
        if (headerFooter != null && headerFooter.getChildObjects() != null && headerFooter.getChildObjects().getCount() > 0) {
            // 目标页眉/页脚同样通过索引获取
            HeaderFooter targetHeaderFooter = targetSection.getHeadersFooters().get(headerFooterType.ordinal());
            targetHeaderFooter.setLinkToPrevious(false);
            targetHeaderFooter.getChildObjects().clear();
            // 遍历源页眉/页脚的子对象并克隆复制
            for (Object childObj : headerFooter.getChildObjects()) {
                if (childObj instanceof DocumentObject) {
                    DocumentObject obj = (DocumentObject) childObj;
                    targetHeaderFooter.getChildObjects().add(obj.deepClone());
                }
            }
        }
    }

    /**
     * 与C#原方法功能完全一致的ReplaceTextRange实现
     * 特点：强制忽略大小写（RegexOptions.IgnoreCase），与caseSensitive参数无关
     */
    public static void replaceTextRange(Document document, String searchText, String replaceText,
                                        boolean caseSensitive, boolean wholeWord) {
        // 查找所有匹配（这里的caseSensitive仅影响FindAllString的查找规则）
        TextSelection[] selections = document.findAllString(searchText, caseSensitive, wholeWord);

        for (TextSelection selection : selections) {
            TextRange textRange = selection.getAsOneRange();
            if (textRange != null) {
                // 关键：强制使用IgnoreCase（与C#的RegexOptions.IgnoreCase一致）
                String regex = Pattern.quote(searchText); // 转义特殊字符，避免正则语法冲突
                String newText = Pattern.compile(regex, Pattern.CASE_INSENSITIVE)
                        .matcher(textRange.getText())
                        .replaceAll(replaceText);

                textRange.setText(newText);
            }
        }
    }

    private static Image InitCreatImage(String imagePath,String OAUrl,int width,int height){
        String downUrl = "";
        try {
            if (NativeExtensionUtils.isNullOrEmpty(imagePath)){
                return null;
            }
            downUrl = imagePath = !imagePath.startsWith("http") ? OAUrl + imagePath : imagePath;
            // 下载图片字节数据（替代C# WebClient.DownloadData）
            byte[] imageData = downloadImageData(downUrl);
            if (imageData == null) {
                return null;
            }
            try (ByteArrayInputStream imageStream = new ByteArrayInputStream(imageData)) {
                BufferedImage image = ImageIO.read(imageStream);
                if (image == null) {
                    return null;
                }

                // 默认宽高为图片原始尺寸
                if (width == 0) width = image.getWidth();
                if (height == 0) height = image.getHeight();

                // 计算缩放比例（保持宽高比）
                int sourceWidth = image.getWidth();
                int sourceHeight = image.getHeight();
                float nPercent = 0;
                float nPercentW = (float) width / sourceWidth;
                float nPercentH = (float) height / sourceHeight;

                nPercent = Math.min(nPercentH, nPercentW); // 取较小比例

                // 目标宽高
                int destWidth = (int) (sourceWidth * nPercent);
                int destHeight = (int) (sourceHeight * nPercent);

                // 创建缩放后的图片（替代C# Bitmap+Graphics）
                BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                Graphics2D graphics = scaledImage.createGraphics();

                // 设置高质量插值（替代InterpolationMode.HighQualityBicubic）
                graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                graphics.drawImage(image, 0, 0, destWidth, destHeight, null);
                graphics.dispose();

                return scaledImage;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 辅助方法：下载图片字节数据（替代C# WebClient.DownloadData）
    private static byte[] downloadImageData(String urlStr) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setConnectTimeout(5000);
        connection.setReadTimeout(5000);

        try (InputStream inputStream = connection.getInputStream();
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {

            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            return outputStream.toByteArray();
        } finally {
            connection.disconnect();
        }
    }

    private static Image Base64ToImage(String base64String) {
        Image image = null;
        try {
            // 空值/空字符串校验
            if (base64String != null && !base64String.trim().isEmpty()) {
                // 正则替换去掉base64前缀（如data:image/png;base64,）
                String pattern = ".*;base64,";
                Pattern regexPattern = Pattern.compile(pattern);
                Matcher matcher = regexPattern.matcher(base64String);
                base64String = matcher.replaceFirst("");

                // Base64解码为字节数组（替代C#的Convert.FromBase64String）
                byte[] imageBytes = Base64.getDecoder().decode(base64String);

                // 字节数组转输入流，读取为Image（替代MemoryStream+Image.FromStream）
                try (ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes)) {
                    BufferedImage bufferedImage = ImageIO.read(inputStream);
                    if (bufferedImage != null) {
                        image = bufferedImage;
                    }
                }
            }
        } catch (Exception e) {
            // 捕获所有异常，返回null（与原逻辑一致）
        }
        return image;
    }

    private static Paragraph GeObjectParagraph(Document document, DocumentObject documentObject) {
        boolean isSelect = false;
        Paragraph lastParagraph = null;
        for (Object secObj : document.getSections()){
            if(secObj instanceof Section){
                Section sec = (Section) secObj;
                for(Object obj : sec.getBody().getChildObjects()){
                    if(obj == documentObject && !isSelect){
                        isSelect = true;
                    }
                    if (obj instanceof Paragraph) {
                        Paragraph para = (Paragraph) obj;
                        if (!isSelect) {
                            isSelect = SelectObject(documentObject, para);
                        }
                        if (isSelect) {
                            lastParagraph = para;
                            break; // 找到后跳出当前循环
                        }
                    }else if (obj instanceof Table) {
                        Table table = (Table) obj;
                        // 遍历Table的行
                        for (Object rowObj : table.getRows()) {
                            if (rowObj instanceof TableRow) {
                                TableRow row = (TableRow) rowObj;
                                // 遍历行的单元格
                                for (Object cellObj : row.getCells()) {
                                    if (cellObj instanceof TableCell) {
                                        TableCell cell = (TableCell) cellObj;
                                        // 遍历单元格的段落
                                        for (Object itemObj : cell.getParagraphs()) {
                                            if (itemObj instanceof Paragraph) {
                                                Paragraph item = (Paragraph) itemObj;
                                                if (!isSelect) {
                                                    isSelect = SelectObject(documentObject, item);
                                                }
                                                if (isSelect) {
                                                    lastParagraph = item;
                                                    break; // 找到后跳出段落循环
                                                }
                                            }
                                        }
                                        if (isSelect) {
                                            break; // 跳出单元格循环
                                        }
                                    }
                                }
                                if (isSelect) {
                                    break; // 跳出行循环
                                }
                            }
                        }
                        if (isSelect) {
                            break; // 跳出Table循环
                        }
                    }
                }
            }
            if (lastParagraph != null) {
                break; // 找到后跳出Section循环
            }
        }
        return lastParagraph;
    }

    private static boolean SelectObject(DocumentObject documentObject, Paragraph paragraph){
        boolean result = false;
        for(Object obj : paragraph.getChildObjects()){
            DocumentObject documentObject2 = (DocumentObject) obj;
            boolean flag =  documentObject2 == documentObject;
            if(flag){
                result = true;
                break;
            }
        }
        return result;
    }

    private static Image InitCreatImage(String imagePath,String OAUrl){
        return InitCreatImage(imagePath,OAUrl,0,0);
    }

    private static void MergeTable(Map<Table, List<Integer>> disMergeDic, Table table, int contentStartIndex, int contentEndIndex, int colCount) {
        try{
            for (int i = 0; i < colCount; i++){
                if(disMergeDic.containsKey(table) && disMergeDic.get(table).contains(i)){
                    continue;
                }
                int startIndex = contentStartIndex;
                int endIndex = contentEndIndex;
                for (int j = contentStartIndex; j <= contentEndIndex; j++){
                    TableRow tableRow = table.getRows().get(j);
                    String cellValue = tableRow.getCells().get(i).getParagraphs().getCount() > 0
                            ? tableRow.getCells().get(i).getParagraphs().get(0).getText()
                            : "";
                    if (j + 1 <= contentEndIndex){
                        TableRow nextTableRow = table.getRows().get(j + 1);
                        String nextCellValue = nextTableRow.getCells().get(i).getParagraphs().getCount() > 0
                                ? nextTableRow.getCells().get(i).getParagraphs().get(0).getText()
                                :"";
                        if (!nextCellValue.equals(cellValue)){
                            if(j > startIndex){
                                for (int start = startIndex + 1; start <= j; start++){
                                    table.getRows().get(start).getCells().get(i).getParagraphs().clear();
                                }
                                table.applyVerticalMerge(i, startIndex, j);
                            }
                            startIndex = j +1;
                        }
                    }
                }
                if (startIndex <= contentEndIndex){
                    for (int start = startIndex + 1; start <= contentEndIndex; start++){
                        table.getRows().get(start).getCells().get(i).getParagraphs().clear();
                    }
                    table.applyVerticalMerge(i, startIndex, contentEndIndex);
                }
            }
        } catch (Exception e) {
            log.debug(String.valueOf(e.getMessage()));
        }
    }


    protected static class GridTarGet {
        public String number;
        public Section targetSection;
        public Table targetTable;
        public int rowIndex;

        public String getNumber() {
            return number;
        }

        public void setNumber(String number) {
            this.number = number;
        }

        public Section getTargetSection() {
            return targetSection;
        }

        public void setTargetSection(Section targetSection) {
            this.targetSection = targetSection;
        }

        public Table getTargetTable() {
            return targetTable;
        }

        public void setTargetTable(Table targetTable) {
            this.targetTable = targetTable;
        }

        public int getRowIndex() {
            return rowIndex;
        }

        public void setRowIndex(int rowIndex) {
            this.rowIndex = rowIndex;
        }
    }
}
