word文档根据标识符填充文本和图片-C#

                //文本填充字典
                var dictionary = new Dictionary<string, PaddingModel>();
                //附件填充字典
                var fileDictionary = new Dictionary<string, PaddingFileModel>();
PaddingModel paddingFileModel = new PaddingModel()
                {
                    ShowType = (int)MESOrderEnums.IndicatorShowType.FixedValue,
                    Text = resultModel.CellValue,
                };
                if (dictionary.ContainsKey("${" + resultModel.CellCode + "}"))
                {
                    // 如果键已经存在,则修改对应的值
                    dictionary[resultModel.CellCode] = paddingFileModel;
                }
                else
                {
                    // 如果键不存在,则添加新的键值对
                    dictionary.Add("${" + resultModel.CellCode + "}", paddingFileModel);
                }
var electronicfile = electronicrecordsfiles.FirstOrDefault(a => a.CellCode == resultModel.CellCode && a.StepCode == resultModel.StepCode && a.ProcedureListCode == floworder.ProcedureListCode && a.Version == floworder.ProcedureListVersion);
                var documentCode = string.Empty;
                if (electronicfile != null)
                    documentCode = electronicfile.DocumentCode;
                //获取数据
                var fileinfo = ifileinfo.QueryWhere($"DocumentCode='{documentCode}' and Visible=1", userApart);
                if (fileinfo != null)
                {
                    PaddingFileModel paddingFileModel = new PaddingFileModel()
                    {
                        ImgWidth = resultModel.ImgWidth ?? 300,
                        ImgHeight = resultModel.ImgHeight ?? 500,
                        FilePath = Path.Combine(XTSystemConfig.FilePath, fileinfo?.DocumentPath ?? "")
                    };
                    if (fileDictionary.ContainsKey("${" + resultModel.CellCode + "}"))
                    {
                        // 如果键已经存在,则修改对应的值
                        fileDictionary[resultModel.CellCode] = paddingFileModel;
                    }
                    else
                    {
                        // 如果键不存在,则添加新的键值对
                        fileDictionary.Add("${" + resultModel.CellCode + "}", paddingFileModel);
                    }
                }
                else
                {
                    PaddingFileModel paddingFileModel = new PaddingFileModel()
                    {
                        ImgWidth = 0,
                        ImgHeight = 0,
                        FilePath = string.Empty,
                        Text = "N/A",
                    };
                    if (fileDictionary.ContainsKey("${" + resultModel.CellCode + "}"))
                    {
                        // 如果键已经存在,则修改对应的值
                        fileDictionary[resultModel.CellCode] = paddingFileModel;
                    }
                    else
                    {
                        // 如果键不存在,则添加新的键值对
                        fileDictionary.Add("${" + resultModel.CellCode + "}", paddingFileModel);
                    }
                }

 var configPath = XTSystemConfig.FilePath;

                        var filePath = Path.Combine(configPath, fileinfo.DocumentPath);

                        using (FileStream templateStream = new FileStream(filePath, System.IO.FileMode.Open, FileAccess.Read))
                        {
                            XWPFDocument document = new XWPFDocument(templateStream);

                            // 替换页眉中的占位符
                            foreach (var header in document.HeaderList)
                            {
                                // 替换页眉表格中的占位符
                                foreach (XWPFTable table in header.Tables)
                                {
                                    foreach (XWPFTableRow row in table.Rows)
                                    {
                                        foreach (XWPFTableCell cell in row.GetTableCells())
                                        {
                                            ifloworder.ReplaceTextInParagraphs(cell.Paragraphs, dictionary, fileDictionary);
                                        }
                                    }
                                }
                            }

                            // 替换表格中的占位符
                            foreach (XWPFTable table in document.Tables)
                            {
                                ifloworder.ProcessTable(table, dictionary, fileDictionary);
                            }

                            // 替换页脚中的占位符
                            foreach (var footer in document.FooterList)
                            {
                                // 替换页脚表格中的占位符
                                foreach (XWPFTable table in footer.Tables)
                                {
                                    foreach (XWPFTableRow row in table.Rows)
                                    {
                                        foreach (XWPFTableCell cell in row.GetTableCells())
                                        {
                                            ifloworder.ReplaceTextInParagraphs(cell.Paragraphs, dictionary, fileDictionary);
                                        }
                                    } 
                                }
                            }

                            using (MemoryStream memoryStream = new MemoryStream())
                            {
                                // 写入更新后的文档
                                document.Write(memoryStream);
                                fileBytes = memoryStream.ToArray();
                            }
                        }
        /// <summary>
        /// 替换占位符
        /// </summary>
        /// <param name="paragraphs"></param>
        /// <param name="replacements"></param>
        /// <param name="filedic"></param> 
        public void ReplaceTextInParagraphs(IEnumerable<XWPFParagraph> paragraphs, Dictionary<string, PaddingModel> replacements, Dictionary<string, PaddingFileModel> filedic)
        {
            foreach (XWPFParagraph paragraph in paragraphs)
            {
                // 拼接段落中的所有文本
                string combinedText = string.Join("", paragraph.Runs.Select(r => r.Text));

                // 在修改前保存原始Run的样式 
                XWPFRun originalRun = null;
                foreach (var run in paragraph.Runs)
                {
                    string text = run.Text;
                    // 检查该 Run 的文本是否包含占位符(即 `${}` 格式)
                    if (text != null && Regex.IsMatch(text, @"\$\{\d+\}"))
                    {
                        originalRun = run;
                        break;
                    }
                }

                CT_RPr originalRPr = originalRun?.GetCTR().rPr;

                //填充文本
                foreach (KeyValuePair<string, PaddingModel> replacement in replacements)
                {
                    string placeholder = replacement.Key;

                    // 优先检查占位符是否存在
                    if (string.IsNullOrEmpty(combinedText) || !combinedText.Contains(placeholder))
                    {
                        continue;
                    }

                    // 合并字典查找操作(优化点1:减少一次字典查找)
                    if (!replacements.TryGetValue(placeholder, out PaddingModel textInfo))
                    {
                        continue;
                    }

                    // 使用正则表达式匹配所有占位符,假设占位符格式为${xxx}
                    string pattern = @"\$\{(\d+)\}";
                    Regex regex = new Regex(pattern);

                    // 匹配所有占位符
                    MatchCollection matches = regex.Matches(combinedText);

                    // 存储所有占位符
                    List<string> placeholders = new List<string>();
                    foreach (Match match in matches)
                    {
                        placeholders.Add(match.Value);  // 可以获取占位符的完整值,如${2410285}
                    }

                    // 如果你需要替换占位符,像下面这样做:
                    foreach (var placeholderItem in placeholders)
                    {
                        PaddingModel valueModel = null;
                        replacements.TryGetValue(placeholderItem, out valueModel);
                        if (valueModel == null)
                            continue;
                        combinedText = combinedText.Replace(placeholderItem, valueModel.Text);// 根据占位符获取替换实际值 
                    }

                    // 复制原有Run的字体样式(如果存在)
                    if (originalRPr != null)
                    {
                        // 清空原有Run
                        for (int i = paragraph.Runs.Count - 1; i >= 0; i--)
                        {
                            paragraph.RemoveRun(i);
                        }

                        // 添加新的Run
                        XWPFRun textNewRun = paragraph.CreateRun();
                        textNewRun.SetText(combinedText ?? "N/A");

                        // 获取新Run的XML对象
                        CT_R newRunCT = textNewRun.GetCTR();

                        // 如果新Run还没有样式属性,创建它
                        if (newRunCT.rPr == null)
                        {
                            newRunCT.rPr = new CT_RPr();
                        }

                        // 复制字体
                        if (originalRPr.rFonts != null)
                        {
                            newRunCT.rPr.rFonts = originalRPr.rFonts;
                        }

                        // 复制字号
                        if (originalRPr.sz != null)
                        {
                            newRunCT.rPr.sz = originalRPr.sz;
                        }

                        // 复制颜色
                        if (originalRPr.color != null)
                        {
                            newRunCT.rPr.color = originalRPr.color;
                        }

                        // 复制粗体/斜体/下划线
                        newRunCT.rPr.b = originalRPr.b;
                        newRunCT.rPr.i = originalRPr.i;
                        newRunCT.rPr.u = originalRPr.u;

                        // 复制字符间距
                        if (originalRPr.spacing != null)
                        {
                            newRunCT.rPr.spacing = originalRPr.spacing;
                        }
                    }
                    else
                    {
                        // 清空原有Run
                        for (int i = paragraph.Runs.Count - 1; i >= 0; i--)
                        {
                            paragraph.RemoveRun(i);
                        }

                        // 添加新的Run
                        XWPFRun textNewRun = paragraph.CreateRun();
                        textNewRun.SetText(combinedText ?? "N/A");
                    }
                }

                string fileText = paragraph.Runs.Select(r => r.Text).FirstOrDefault();

                //填充附件
                foreach (KeyValuePair<string, PaddingFileModel> replacement in filedic)
                {
                    string placeholder = replacement.Key;

                    // 优先检查占位符是否存在
                    if (string.IsNullOrEmpty(fileText) || !fileText.Contains(placeholder))
                    {
                        continue;
                    }

                    // 合并字典查找操作(优化点1:减少一次字典查找)
                    if (!filedic.TryGetValue(placeholder, out PaddingFileModel fileInfo))
                    {
                        continue;
                    }

                    if (fileInfo.Text == "N/A")
                    {
                        // 复制原有Run的字体样式(如果存在)
                        if (originalRPr != null)
                        {
                            // 清空原有Run
                            for (int i = paragraph.Runs.Count - 1; i >= 0; i--)
                            {
                                paragraph.RemoveRun(i);
                            }

                            // 添加新的Run
                            XWPFRun textNewRun = paragraph.CreateRun();
                            textNewRun.SetText("N/A");

                            // 获取新Run的XML对象
                            CT_R newRunCT = textNewRun.GetCTR();

                            // 如果新Run还没有样式属性,创建它
                            if (newRunCT.rPr == null)
                            {
                                newRunCT.rPr = new CT_RPr();
                            }

                            // 复制字体
                            if (originalRPr.rFonts != null)
                            {
                                newRunCT.rPr.rFonts = originalRPr.rFonts;
                            }

                            // 复制字号
                            if (originalRPr.sz != null)
                            {
                                newRunCT.rPr.sz = originalRPr.sz;
                            }

                            // 复制颜色
                            if (originalRPr.color != null)
                            {
                                newRunCT.rPr.color = originalRPr.color;
                            }

                            // 复制粗体/斜体/下划线
                            newRunCT.rPr.b = originalRPr.b;
                            newRunCT.rPr.i = originalRPr.i;
                            newRunCT.rPr.u = originalRPr.u;

                            // 复制字符间距
                            if (originalRPr.spacing != null)
                            {
                                newRunCT.rPr.spacing = originalRPr.spacing;
                            }
                        }
                        else
                        {
                            // 清空原有Run
                            for (int i = paragraph.Runs.Count - 1; i >= 0; i--)
                            {
                                paragraph.RemoveRun(i);
                            }

                            // 添加新的Run
                            XWPFRun textNewRun = paragraph.CreateRun();
                            textNewRun.SetText(combinedText ?? "N/A");
                        }

                        continue;
                    }

                    // 验证文件信息(优化点3:参数校验前置)
                    if (string.IsNullOrWhiteSpace(fileInfo?.FilePath))
                    {
                        continue;
                    }

                    // 使用File.Exists替代空值判断(优化点4:增强文件检测)
                    if (!File.Exists(fileInfo.FilePath))
                    {
                        continue;
                    }

                    //在图片插入前调整段落属性
                    paragraph.SpacingLineRule = LineSpacingRule.ATLEAST;

                    using (FileStream picFile = new FileStream(
                        fileInfo.FilePath,
                        FileMode.Open,
                        FileAccess.Read,
                        FileShare.Read,
                        bufferSize: 4096,
                        FileOptions.SequentialScan))
                    {
                        // 验证图片有效性
                        try
                        {
                            using (Image testImage = Image.FromStream(picFile)) { }
                            picFile.Position = 0;
                        }
                        catch
                        {
                            continue; // 跳过无效图片
                        }

                        // 设置默认尺寸
                        if (fileInfo.ImgWidth == 0) fileInfo.ImgWidth = 500;
                        if (fileInfo.ImgHeight == 0) fileInfo.ImgHeight = 500;

                        // 加载原始图片
                        using (Image originalImage = Image.FromStream(picFile))
                        {
                            using (MemoryStream rotatedStream = new MemoryStream())
                            {
                                originalImage.Save(rotatedStream, ImageFormat.Png);
                                rotatedStream.Position = 0;

                                int emuWidth = Units.ToEMU(fileInfo.ImgWidth);
                                int emuHeight = Units.ToEMU(fileInfo.ImgHeight);

                                // 清空原有Run
                                for (int i = paragraph.Runs.Count - 1; i >= 0; i--)
                                {
                                    paragraph.RemoveRun(i);
                                }
                                // 添加新Run
                                XWPFRun fileNewRun = paragraph.CreateRun();
                                fileNewRun.AddPicture(rotatedStream, (int)PictureType.PNG, "image", emuWidth, emuHeight);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 递归处理表格
        /// </summary>
        /// <param name="table"></param>
        /// <param name="replacements"></param>
        /// <param name="filedic"></param>
        public void ProcessTable(XWPFTable table, Dictionary<string, PaddingModel> replacements, Dictionary<string, PaddingFileModel> filedic)
        {
            foreach (XWPFTableRow row in table.Rows)
            {
                foreach (XWPFTableCell cell in row.GetTableCells())
                {
                    //根据标识符填充段落
                    ReplaceTextInParagraphs(cell.Paragraphs, replacements, filedic);

                    if (cell.Tables != null && cell.Tables.Any())
                    {
                        foreach (var item in cell.Tables)
                        {
                            ProcessTable(item, replacements, filedic);
                        }
                    }
                }
            }
        }

 

posted @ 2025-07-08 10:06  黑山羊里的白山羊  阅读(16)  评论(0)    收藏  举报