在工作中,由于会需要对word模板进行数据填充,并导出为新文件,便对word相关的类库做了简单的了解。
1.NPOI
NPOI对excel的支持相当给力,但是对于word的支持却明显不到位,我在使用时导出新文件始终报错无法打开。
功能强大,专业,支持全面。商业化软件,需要收费,有免费版不过有限制(会在文档里加上版权文字,可以删掉。。。)
3.OpenXml
较为底层的操作OpenXml文档的类库,提供了对word的支持,功能全面,速度快。
对word文档的操作,在我的需求里 主要是填充word表格的数据 和替换段落的标签数据。下面附代码
需要使用到DocumentFormat.OpenXml类库,nuget:install-package DocumentFormat.OpemXml
/// <summary> /// 设置表格数据 /// </summary> /// <param name="tableIndex">表格索引</param> /// <param name="datatable">数据表</param> /// <param name="configs">数据配置</param> /// <param name="headSpan">表头占用行数</param> public void SetTableData(int tableIndex, DataTable datatable, IList<WordTableColumnConfig> configs, int headSpan = 1) { if (doc == null) throw new Exception("word parse failed."); if (tableIndex < 0 || tableIndex > Tables.Count - 1) throw new Exception("tableIndex is out of range."); if (datatable == null) throw new Exception("datatable can not be null."); if (configs == null || configs.Count == 0) throw new Exception("configs can not be null or less than 0."); if (datatable.Rows.Count == 0) return; for (int i = 0; i < datatable.Rows.Count; i++) { int rowIndex = i + headSpan; SetTableData(tableIndex, rowIndex, datatable.Rows[i], configs); } } /// <summary> /// 设置表格数据 /// </summary> /// <param name="tableIndex">表格索引</param> /// <param name="rowIndex">数据表格的行索引</param> /// <param name="dataRow">数据行</param> /// <param name="configs">数据列配置</param> public void SetTableData(int tableIndex, int rowIndex, DataRow dataRow, IList<WordTableColumnConfig> configs) { if (doc == null) throw new Exception("word parse failed."); if (tableIndex < 0 || tableIndex > Tables.Count - 1) throw new Exception("tableIndex is out of range."); if (dataRow == null) throw new Exception("dataRow can not be null."); if (configs == null || configs.Count == 0) throw new Exception("configs can not be null or less than 0."); if (rowIndex < 0) throw new Exception("rowIndex can not be less than 0."); if (rowIndex > Tables[tableIndex].ChildElements.Count - 2) return; rowIndex += 2; foreach (var config in configs) { if (!dataRow.Table.Columns.Contains(config.ColumnName)) continue; string value = dataRow[config.ColumnName] == null ? string.Empty : dataRow[config.ColumnName].ToString(); DocumentFormat.OpenXml.Wordprocessing.TableCell cell = (DocumentFormat.OpenXml.Wordprocessing.TableCell)Tables[tableIndex].ChildElements[rowIndex].ChildElements[config.WordColumnIndex + 1]; DocumentFormat.OpenXml.Wordprocessing.Paragraph p = new DocumentFormat.OpenXml.Wordprocessing.Paragraph(); p.PrependChild<DocumentFormat.OpenXml.Wordprocessing.Run>(new DocumentFormat.OpenXml.Wordprocessing.Run()); var run = p.Elements<DocumentFormat.OpenXml.Wordprocessing.Run>().First(); run.PrependChild<DocumentFormat.OpenXml.Wordprocessing.Text>(new DocumentFormat.OpenXml.Wordprocessing.Text() { Text = value }); cell.AppendChild<DocumentFormat.OpenXml.Wordprocessing.Paragraph>(p); } }
/// <summary> /// 设置标签数据 /// </summary> /// <param name="lableData">标签数据</param> public void SetLableData(Dictionary<string, string> lableData) { if (doc == null) throw new Exception("word parse failed."); if (lableData == null) throw new Exception("lableData can not be null."); if (Paragraphs.Count == 0) return; var items = lableData.GetEnumerator(); while (items.MoveNext()) { var item = items.Current; foreach (var paragraph in Paragraphs) { if (!paragraph.InnerText.Contains(item.Key)) continue; var run = paragraph.Elements<DocumentFormat.OpenXml.Wordprocessing.Run>().FirstOrDefault(g => g.InnerText.Trim() == item.Key); var text = run?.Elements<DocumentFormat.OpenXml.Wordprocessing.Text>().FirstOrDefault(g => g.Text.Trim() == item.Key); if (text != null) { text.Text = item.Value; } } } }
第一次发博文,如果有问题,欢迎指出,欢迎交流。