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); } } } } }