.NET驾驭Word之力:结构化文档元素操作
在前几篇文章中,我们学习了Word对象模型的基础知识、文本操作与格式设置等内容。掌握了这些基础知识后,我们现在可以进一步深入到文档的结构化元素操作,包括段落与节的管理、表格的创建与操作以及图片的插入等。
本文将详细介绍如何使用MudTools.OfficeInterop.Word库来操作Word文档中的结构化元素,包括段落与节的使用、表格的自动化操作以及图片与形状的插入。最后,我们将通过一个实战示例——创建一个包含多种结构化元素的员工信息表,来综合运用所学知识。
使用段落(Paragraphs)与节(Sections)
段落和节是Word文档中重要的结构化元素。段落用于组织文本内容,而节则用于对文档进行分段,以便为不同部分设置不同的页面布局。
遍历文档中的所有段落
在处理Word文档时,经常需要遍历文档中的所有段落以进行批量操作。通过Paragraphs属性,我们可以轻松访问文档中的所有段落。
using MudTools.OfficeInterop;
using MudTools.OfficeInterop.Word;
// 打开现有文档
using var wordApp = WordFactory.Open(@"C:\Documents\SampleDocument.docx");
var document = wordApp.ActiveDocument;
// 遍历文档中的所有段落
foreach (var paragraph in document.Paragraphs)
{
// 输出段落文本
Console.WriteLine(paragraph.GetText());
// 为每个段落设置12磅的段后间距
paragraph.SpaceAfter = 12;
// 为每个段落设置1.5倍行距
paragraph.LineSpacingRule = WdLineSpacing.wdLineSpace15;
}
// 或者通过索引访问特定段落
for (int i = 1; i <= document.ParagraphCount; i++)
{
var paragraph = document.Paragraphs[i];
// 处理段落内容
Console.WriteLine($"第{i}段: {paragraph.GetText()}");
}
在上面的示例中,我们展示了两种遍历段落的方式:使用foreach循环和通过索引访问。每种方式都有其适用场景,foreach循环适用于需要处理所有段落的情况,而索引访问适用于需要精确控制处理顺序或只处理特定段落的情况。
应用场景:文档格式标准化
在企业环境中,经常需要对大量文档进行格式标准化处理。例如,确保所有文档的段落间距、行距、字体等符合公司规范。
/// <summary>
/// 文档格式标准化工具
/// </summary>
public class DocumentFormatter
{
/// <summary>
/// 标准化文档格式
/// </summary>
/// <param name="documentPath">文档路径</param>
public void StandardizeDocument(string documentPath)
{
try
{
// 打开文档
using var wordApp = WordFactory.Open(documentPath);
var document = wordApp.ActiveDocument;
// 隐藏Word应用程序以提高性能
wordApp.Visibility = WordAppVisibility.Hidden;
wordApp.DisplayAlerts = WdAlertLevel.wdAlertsNone;
// 遍历所有段落并标准化格式
foreach (var paragraph in document.Paragraphs)
{
// 设置段落格式
paragraph.SpaceAfter = 12; // 段后间距12磅
paragraph.SpaceBefore = 0; // 段前间距0磅
paragraph.LineSpacingRule = WdLineSpacing.wdLineSpace15; // 1.5倍行距
// 设置字体格式
paragraph.Range.Font.Name = "微软雅黑";
paragraph.Range.Font.Size = 10.5f;
// 设置对齐方式
paragraph.Alignment = WdParagraphAlignment.wdAlignParagraphJustify; // 两端对齐
}
// 保存文档
document.Save();
document.Close();
Console.WriteLine($"文档 {documentPath} 格式标准化完成");
}
catch (Exception ex)
{
Console.WriteLine($"格式标准化过程中发生错误: {ex.Message}");
}
}
}
使用节(Section)为文档的不同部分设置不同的页面布局
节是Word文档中用于分隔具有不同页面布局设置的区域。通过节,我们可以为文档的不同部分设置不同的页眉页脚、纸张方向、页边距等。
// 添加新节并设置不同的页面方向
var sections = document.Sections;
// 获取当前节的数量
int sectionCount = sections.Count;
// 在文档末尾添加分节符以创建新节
document.AddSectionBreak(document.Content.End - 1, (int)WdSectionBreakType.wdSectionBreakNextPage);
// 获取新添加的节
var newSection = sections[sectionCount + 1];
// 为新节设置横向页面
newSection.PageSetup.Orientation = WdOrientation.wdOrientLandscape;
// 为不同节设置不同的页眉
var firstSectionHeader = sections[1].Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary];
firstSectionHeader.Range.Text = "这是第一节的页眉";
var newSectionHeader = newSection.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary];
newSectionHeader.Range.Text = "这是新节的页眉";
通过以上代码,我们可以为文档的不同部分设置不同的页面布局。这对于制作包含多种内容类型的复杂文档非常有用,例如在同一篇文档中既有纵向的文字说明,又有横向的表格数据。
应用场景:制作混合布局报告
在制作技术报告或商业文档时,经常需要在同一篇文档中包含不同类型的页面布局。例如,文档正文使用纵向布局,而数据表格使用横向布局。
/// <summary>
/// 混合布局报告生成器
/// </summary>
public class MixedLayoutReportGenerator
{
/// <summary>
/// 生成混合布局报告
/// </summary>
/// <param name="templatePath">模板路径</param>
/// <param name="outputPath">输出路径</param>
public void GenerateReport(string templatePath, string outputPath)
{
try
{
// 基于模板创建文档
using var wordApp = WordFactory.CreateFrom(templatePath);
var document = wordApp.ActiveDocument;
// 隐藏Word应用程序
wordApp.Visibility = WordAppVisibility.Hidden;
wordApp.DisplayAlerts = WdAlertLevel.wdAlertsNone;
// 在文档末尾添加分节符,创建新节用于横向表格
document.AddSectionBreak(document.Content.End - 1,
(int)WdSectionBreakType.wdSectionBreakNextPage);
// 获取新节
var dataSection = document.Sections[document.Sections.Count];
// 设置新节为横向布局
dataSection.PageSetup.Orientation = WdOrientation.wdOrientLandscape;
// 在新节中添加标题
var range = dataSection.Range;
range.Collapse(WdCollapseDirection.wdCollapseStart);
range.Text = "数据汇总表\n";
range.Font.Bold = 1;
range.Font.Size = 14;
range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
// 添加表格
range.Collapse(WdCollapseDirection.wdCollapseEnd);
var table = document.Tables.Add(range, 10, 6); // 10行6列的表格
// 填充表格数据
PopulateTableData(table);
// 保存文档
document.SaveAs(outputPath, WdSaveFormat.wdFormatXMLDocument);
document.Close();
Console.WriteLine($"混合布局报告已生成: {outputPath}");
}
catch (Exception ex)
{
Console.WriteLine($"生成报告时发生错误: {ex.Message}");
}
}
/// <summary>
/// 填充表格数据
/// </summary>
/// <param name="table">表格对象</param>
private void PopulateTableData(IWordTable table)
{
// 表头
string[] headers = { "序号", "产品名称", "销售数量", "单价", "总金额", "备注" };
for (int i = 0; i < headers.Length; i++)
{
table.Cell(1, i + 1).Range.Text = headers[i];
table.Cell(1, i + 1).Range.Font.Bold = 1;
table.Cell(1, i + 1).VerticalAlignment =
WdCellVerticalAlignment.wdCellAlignVerticalCenter;
}
// 示例数据
string[,] data = {
{"1", "产品A", "100", "50.00", "5000.00", ""},
{"2", "产品B", "200", "30.00", "6000.00", ""},
{"3", "产品C", "150", "40.00", "6000.00", ""},
{"4", "产品D", "80", "70.00", "5600.00", ""},
{"5", "产品E", "120", "35.00", "4200.00", ""}
};
// 填充数据
for (int i = 0; i < data.GetLength(0); i++)
{
for (int j = 0; j < data.GetLength(1); j++)
{
table.Cell(i + 2, j + 1).Range.Text = data[i, j];
table.Cell(i + 2, j + 1).VerticalAlignment =
WdCellVerticalAlignment.wdCellAlignVerticalCenter;
}
}
// 设置表格样式
table.Borders.Enable = 1;
table.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent;
table.PreferredWidth = 100;
}
}
表格(Table)的自动化
表格是Word文档中用于组织和展示数据的重要元素。MudTools.OfficeInterop.Word库提供了丰富的API来创建、操作和格式化表格。
创建指定行数列的表格
使用Tables.Add方法,我们可以轻松地在文档中创建指定行列数的表格。
// 在文档末尾创建一个5行4列的表格
var range = document.Content;
range.Collapse(WdCollapseDirection.wdCollapseEnd); // 将范围折叠到末尾
var table = document.Tables.Add(range, 5, 4);
// 设置表格标题行
table.Rows[1].Cells[1].Range.Text = "姓名";
table.Rows[1].Cells[2].Range.Text = "部门";
table.Rows[1].Cells[3].Range.Text = "职位";
table.Rows[1].Cells[4].Range.Text = "入职日期";
// 填充表格数据
string[,] employeeData = {
{"张三", "技术部", "软件工程师", "2022-01-15"},
{"李四", "市场部", "市场专员", "2021-11-20"},
{"王五", "人事部", "人事经理", "2020-05-10"},
{"赵六", "财务部", "会计师", "2022-03-08"}
};
for (int i = 0; i < employeeData.GetLength(0); i++)
{
for (int j = 0; j < employeeData.GetLength(1); j++)
{
table.Cell(i + 2, j + 1).Range.Text = employeeData[i, j];
}
}
// 设置标题行为粗体
for (int i = 1; i <= 4; i++)
{
table.Cell(1, i).Range.Font.Bold = 1;
}
遍历单元格、写入数据、设置表格样式和边框
创建表格后,我们需要填充数据并设置样式。
// 设置表格样式
table.TableStyle = "网格型";
// 设置表格边框
table.Borders.Enable = 1;
table.Borders.LineStyle = WdLineStyle.wdLineStyleSingle;
table.Borders.LineWidth = WdLineWidth.wdLineWidth150pt;
// 遍历所有单元格并设置对齐方式
foreach (var row in table.Rows)
{
foreach (var cell in row.Cells)
{
cell.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
cell.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
}
}
// 设置表格宽度
table.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent;
table.PreferredWidth = 100;
单元格合并与拆分
在实际应用中,我们经常需要合并或拆分单元格以满足不同的布局需求。
// 合并单元格示例:合并第一行的所有单元格作为标题
var firstRow = table.Rows[1];
firstRow.Cells[1].Merge(firstRow.Cells[4]);
// 在合并后的单元格中添加标题文本
firstRow.Cells[1].Range.Text = "员工信息表";
firstRow.Cells[1].Range.Font.Bold = 1;
firstRow.Cells[1].Range.Font.Size = 14;
firstRow.Cells[1].Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
// 拆分单元格示例:拆分指定单元格
var cellToSplit = table.Cell(3, 2);
cellToSplit.Split(2, 1); // 拆分为2行1列
应用场景:自动化生成财务报表
在财务部门,经常需要生成各种财务报表,这些报表通常包含复杂的表格结构。通过自动化生成,可以大大提高工作效率并减少错误。
/// <summary>
/// 财务报表生成器
/// </summary>
public class FinancialReportGenerator
{
/// <summary>
/// 生成财务报表
/// </summary>
/// <param name="financialData">财务数据</param>
/// <param name="outputPath">输出路径</param>
public void GenerateFinancialReport(FinancialData financialData, string outputPath)
{
try
{
// 创建新文档
using var wordApp = WordFactory.BlankWorkbook();
var document = wordApp.ActiveDocument;
// 隐藏Word应用程序
wordApp.Visibility = WordAppVisibility.Hidden;
wordApp.DisplayAlerts = WdAlertLevel.wdAlertsNone;
// 添加标题
AddReportTitle(document, "年度财务报告");
// 添加报告基本信息
AddReportInfo(document, financialData);
// 添加收入明细表
AddIncomeStatement(document, financialData.IncomeItems);
// 添加资产负债表
AddBalanceSheet(document, financialData.Assets, financialData.Liabilities,
financialData.Equity);
// 保存文档
document.SaveAs(outputPath, WdSaveFormat.wdFormatXMLDocument);
document.Close();
Console.WriteLine($"财务报告已生成: {outputPath}");
}
catch (Exception ex)
{
Console.WriteLine($"生成财务报告时发生错误: {ex.Message}");
}
}
/// <summary>
/// 添加报告标题
/// </summary>
/// <param name="document">文档对象</param>
/// <param name="title">标题文本</param>
private void AddReportTitle(IWordDocument document, string title)
{
var titleParagraph = document.AddParagraph(0, title);
titleParagraph.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
titleParagraph.Range.Font.Name = "微软雅黑";
titleParagraph.Range.Font.Size = 18;
titleParagraph.Range.Font.Bold = 1;
// 添加空行
document.AddParagraph(document.Content.End - 1);
}
/// <summary>
/// 添加报告基本信息
/// </summary>
/// <param name="document">文档对象</param>
/// <param name="financialData">财务数据</param>
private void AddReportInfo(IWordDocument document, FinancialData financialData)
{
var infoParagraph = document.AddParagraph(document.Content.End - 1,
$"报告期间: {financialData.Period}\n" +
$"编制单位: {financialData.CompanyName}\n" +
$"货币单位: 人民币元\n");
infoParagraph.Range.Font.Name = "微软雅黑";
infoParagraph.Range.Font.Size = 12;
// 添加空行
document.AddParagraph(document.Content.End - 1);
}
/// <summary>
/// 添加收入明细表
/// </summary>
/// <param name="document">文档对象</param>
/// <param name="incomeItems">收入项目</param>
private void AddIncomeStatement(IWordDocument document, List<IncomeItem> incomeItems)
{
// 添加表标题
var titleParagraph = document.AddParagraph(document.Content.End - 1, "一、收入明细表");
titleParagraph.Range.Font.Bold = 1;
titleParagraph.Range.Font.Size = 14;
// 添加空行
document.AddParagraph(document.Content.End - 1);
// 创建表格
var range = document.Content;
range.Collapse(WdCollapseDirection.wdCollapseEnd);
var table = document.Tables.Add(range, incomeItems.Count + 2, 4); // 数据行+标题行+合计行
// 设置表头
string[] headers = { "项目", "本期金额", "上期金额", "增减率(%)" };
for (int i = 0; i < headers.Length; i++)
{
var cell = table.Cell(1, i + 1);
cell.Range.Text = headers[i];
cell.Range.Font.Bold = 1;
cell.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
cell.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
}
// 填充数据
decimal totalCurrent = 0, totalPrevious = 0;
for (int i = 0; i < incomeItems.Count; i++)
{
var item = incomeItems[i];
table.Cell(i + 2, 1).Range.Text = item.Name;
table.Cell(i + 2, 2).Range.Text = item.CurrentAmount.ToString("N2");
table.Cell(i + 2, 3).Range.Text = item.PreviousAmount.ToString("N2");
table.Cell(i + 2, 4).Range.Text = item.ChangeRate.ToString("F2");
totalCurrent += item.CurrentAmount;
totalPrevious += item.PreviousAmount;
// 设置对齐方式
for (int j = 1; j <= 4; j++)
{
table.Cell(i + 2, j).VerticalAlignment =
WdCellVerticalAlignment.wdCellAlignVerticalCenter;
if (j > 1)
{
table.Cell(i + 2, j).Range.ParagraphFormat.Alignment =
WdParagraphAlignment.wdAlignParagraphRight;
}
}
}
// 添加合计行
table.Cell(incomeItems.Count + 2, 1).Range.Text = "合计";
table.Cell(incomeItems.Count + 2, 1).Range.Font.Bold = 1;
table.Cell(incomeItems.Count + 2, 2).Range.Text = totalCurrent.ToString("N2");
table.Cell(incomeItems.Count + 2, 2).Range.Font.Bold = 1;
table.Cell(incomeItems.Count + 2, 3).Range.Text = totalPrevious.ToString("N2");
table.Cell(incomeItems.Count + 2, 3).Range.Font.Bold = 1;
var totalChangeRate = totalPrevious != 0 ?
(totalCurrent - totalPrevious) / totalPrevious * 100 : 0;
table.Cell(incomeItems.Count + 2, 4).Range.Text = totalChangeRate.ToString("F2");
table.Cell(incomeItems.Count + 2, 4).Range.Font.Bold = 1;
// 设置合计行对齐方式
for (int j = 1; j <= 4; j++)
{
table.Cell(incomeItems.Count + 2, j).VerticalAlignment =
WdCellVerticalAlignment.wdCellAlignVerticalCenter;
if (j > 1)
{
table.Cell(incomeItems.Count + 2, j).Range.ParagraphFormat.Alignment =
WdParagraphAlignment.wdAlignParagraphRight;
}
}
// 设置表格样式
table.Borders.Enable = 1;
table.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent;
table.PreferredWidth = 100;
// 添加空行
document.AddParagraph(document.Content.End - 1);
document.AddParagraph(document.Content.End - 1);
}
/// <summary>
/// 添加资产负债表
/// </summary>
/// <param name="document">文档对象</param>
/// <param name="assets">资产项目</param>
/// <param name="liabilities">负债项目</param>
/// <param name="equity">权益项目</param>
private void AddBalanceSheet(IWordDocument document, List<AssetItem> assets,
List<LiabilityItem> liabilities, List<EquityItem> equity)
{
// 添加表标题
var titleParagraph = document.AddParagraph(document.Content.End - 1, "二、资产负债表");
titleParagraph.Range.Font.Bold = 1;
titleParagraph.Range.Font.Size = 14;
// 添加空行
document.AddParagraph(document.Content.End - 1);
// 创建表格
var range = document.Content;
range.Collapse(WdCollapseDirection.wdCollapseEnd);
var table = document.Tables.Add(range,
Math.Max(assets.Count, liabilities.Count + equity.Count) + 1, 4);
// 设置表头
table.Cell(1, 1).Range.Text = "资产";
table.Cell(1, 1).Range.Font.Bold = 1;
table.Cell(1, 2).Range.Text = "金额";
table.Cell(1, 2).Range.Font.Bold = 1;
table.Cell(1, 3).Range.Text = "负债和权益";
table.Cell(1, 3).Range.Font.Bold = 1;
table.Cell(1, 4).Range.Text = "金额";
table.Cell(1, 4).Range.Font.Bold = 1;
// 设置表头格式
for (int i = 1; i <= 4; i++)
{
table.Cell(1, i).VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(1, i).Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
}
// 填充资产数据
for (int i = 0; i < assets.Count; i++)
{
table.Cell(i + 2, 1).Range.Text = assets[i].Name;
table.Cell(i + 2, 2).Range.Text = assets[i].Amount.ToString("N2");
// 设置格式
table.Cell(i + 2, 1).VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(i + 2, 2).VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(i + 2, 2).Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphRight;
}
// 填充负债和权益数据
int liabilityStartRow = 2;
for (int i = 0; i < liabilities.Count; i++)
{
table.Cell(i + liabilityStartRow, 3).Range.Text = liabilities[i].Name;
table.Cell(i + liabilityStartRow, 4).Range.Text = liabilities[i].Amount.ToString("N2");
// 设置格式
table.Cell(i + liabilityStartRow, 3).VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(i + liabilityStartRow, 4).VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(i + liabilityStartRow, 4).Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphRight;
}
// 填充权益数据
int equityStartRow = liabilityStartRow + liabilities.Count;
for (int i = 0; i < equity.Count; i++)
{
table.Cell(i + equityStartRow, 3).Range.Text = equity[i].Name;
table.Cell(i + equityStartRow, 4).Range.Text = equity[i].Amount.ToString("N2");
// 设置格式
table.Cell(i + equityStartRow, 3).VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(i + equityStartRow, 4).VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(i + equityStartRow, 4).Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphRight;
}
// 计算资产合计
decimal totalAssets = assets.Sum(a => a.Amount);
table.Cell(assets.Count + 2, 1).Range.Text = "资产总计";
table.Cell(assets.Count + 2, 1).Range.Font.Bold = 1;
table.Cell(assets.Count + 2, 2).Range.Text = totalAssets.ToString("N2");
table.Cell(assets.Count + 2, 2).Range.Font.Bold = 1;
// 计算负债和权益合计
decimal totalLiabilities = liabilities.Sum(l => l.Amount);
decimal totalEquity = equity.Sum(e => e.Amount);
table.Cell(Math.Max(assets.Count, liabilities.Count + equity.Count) + 1, 3).Range.Text = "负债和权益总计";
table.Cell(Math.Max(assets.Count, liabilities.Count + equity.Count) + 1, 3).Range.Font.Bold = 1;
table.Cell(Math.Max(assets.Count, liabilities.Count + equity.Count) + 1, 4).Range.Text =
(totalLiabilities + totalEquity).ToString("N2");
table.Cell(Math.Max(assets.Count, liabilities.Count + equity.Count) + 1, 4).Range.Font.Bold = 1;
// 设置表格样式
table.Borders.Enable = 1;
table.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent;
table.PreferredWidth = 100;
}
}
/// <summary>
/// 财务数据模型
/// </summary>
public class FinancialData
{
/// <summary>
/// 报告期间
/// </summary>
public string Period { get; set; }
/// <summary>
/// 公司名称
/// </summary>
public string CompanyName { get; set; }
/// <summary>
/// 收入项目列表
/// </summary>
public List<IncomeItem> IncomeItems { get; set; }
/// <summary>
/// 资产项目列表
/// </summary>
public List<AssetItem> Assets { get; set; }
/// <summary>
/// 负债项目列表
/// </summary>
public List<LiabilityItem> Liabilities { get; set; }
/// <summary>
/// 权益项目列表
/// </summary>
public List<EquityItem> Equity { get; set; }
}
/// <summary>
/// 收入项目
/// </summary>
public class IncomeItem
{
/// <summary>
/// 项目名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 本期金额
/// </summary>
public decimal CurrentAmount { get; set; }
/// <summary>
/// 上期金额
/// </summary>
public decimal PreviousAmount { get; set; }
/// <summary>
/// 增减率
/// </summary>
public decimal ChangeRate => PreviousAmount != 0 ?
(CurrentAmount - PreviousAmount) / PreviousAmount * 100 : 0;
}
/// <summary>
/// 资产项目
/// </summary>
public class AssetItem
{
/// <summary>
/// 项目名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 金额
/// </summary>
public decimal Amount { get; set; }
}
/// <summary>
/// 负债项目
/// </summary>
public class LiabilityItem
{
/// <summary>
/// 项目名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 金额
/// </summary>
public decimal Amount { get; set; }
}
/// <summary>
/// 权益项目
/// </summary>
public class EquityItem
{
/// <summary>
/// 项目名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 金额
/// </summary>
public decimal Amount { get; set; }
}
图片与形状的插入
图片和形状能够丰富文档的视觉效果,使其更加生动和易于理解。Word提供了两种类型的图形对象:内嵌形状和浮动形状。
使用InlineShapes.AddPicture方法插入图片
内嵌形状是嵌入在文本行中的对象,它们随着文本移动而移动。
// 在文档末尾插入内嵌图片
var range = document.Content;
range.Collapse(WdCollapseDirection.wdCollapseEnd);
// 使用InlineShapes.AddPicture方法插入图片
var inlineShape = document.InlineShapes.AddPicture(
fileName: @"C:\Images\company_logo.png",
linkToFile: false, // 不链接到文件
saveWithDocument: true // 与文档一起保存
);
// 设置图片大小
inlineShape.Width = 100;
inlineShape.Height = 50;
// 添加图片说明文字
range.InsertAfter("\n公司Logo\n");
使用Shapes.AddPicture方法插入浮动图片并设置环绕方式
浮动形状是独立于文本流的对象,可以放置在页面上的任意位置,并可以设置文字环绕方式。
// 插入浮动图片
var shape = document.Shapes.AddPicture(
fileName: @"C:\Images\decorative_image.png",
linkToFile: false,
saveWithDocument: true,
left: 300, // 距离页面左边距300磅
top: 150, // 距离页面上边距150磅
width: 150,
height: 100
);
// 设置图片的环绕方式
shape.WrapFormat.Type = WdWrapType.wdWrapSquare;
shape.WrapFormat.DistanceTop = 10;
shape.WrapFormat.DistanceBottom = 10;
shape.WrapFormat.DistanceLeft = 10;
shape.WrapFormat.DistanceRight = 10;
// 设置图片的相对位置
shape.RelativeHorizontalPosition = WdRelativeHorizontalPosition.wdRelativeHorizontalPositionPage;
shape.RelativeVerticalPosition = WdRelativeVerticalPosition.wdRelativeVerticalPositionPage;
应用场景:自动化制作产品宣传册
在市场营销领域,经常需要制作产品宣传册。通过自动化生成,可以快速制作大量标准化的宣传材料。
/// <summary>
/// 产品宣传册生成器
/// </summary>
public class ProductBrochureGenerator
{
/// <summary>
/// 生成产品宣传册
/// </summary>
/// <param name="products">产品列表</param>
/// <param name="templatePath">模板路径</param>
/// <param name="outputPath">输出路径</param>
public void GenerateBrochure(List<Product> products, string templatePath, string outputPath)
{
try
{
// 基于模板创建文档
using var wordApp = WordFactory.CreateFrom(templatePath);
var document = wordApp.ActiveDocument;
// 隐藏Word应用程序
wordApp.Visibility = WordAppVisibility.Hidden;
wordApp.DisplayAlerts = WdAlertLevel.wdAlertsNone;
// 为每个产品添加页面
foreach (var product in products)
{
AddProductPage(document, product);
}
// 保存文档
document.SaveAs(outputPath, WdSaveFormat.wdFormatXMLDocument);
document.Close();
Console.WriteLine($"产品宣传册已生成: {outputPath}");
}
catch (Exception ex)
{
Console.WriteLine($"生成产品宣传册时发生错误: {ex.Message}");
}
}
/// <summary>
/// 添加产品页面
/// </summary>
/// <param name="document">文档对象</param>
/// <param name="product">产品信息</param>
private void AddProductPage(IWordDocument document, Product product)
{
// 添加分页符
document.AddPageBreak(document.Content.End - 1);
// 添加产品名称
var titleParagraph = document.AddParagraph(document.Content.End - 1, product.Name);
titleParagraph.Range.Font.Name = "微软雅黑";
titleParagraph.Range.Font.Size = 24;
titleParagraph.Range.Font.Bold = 1;
titleParagraph.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
titleParagraph.SpaceAfter = 20;
// 添加产品图片
if (File.Exists(product.ImagePath))
{
var range = document.Content;
range.Collapse(WdCollapseDirection.wdCollapseEnd);
var inlineShape = document.InlineShapes.AddPicture(
fileName: product.ImagePath,
linkToFile: false,
saveWithDocument: true
);
// 设置图片大小(保持纵横比)
inlineShape.LockAspectRatio = true;
if (inlineShape.Width > 300)
{
inlineShape.Width = 300;
}
// 居中对齐图片
range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
// 添加空行
document.AddParagraph(document.Content.End - 1);
}
// 添加产品描述
var descriptionParagraph = document.AddParagraph(document.Content.End - 1, product.Description);
descriptionParagraph.Range.Font.Name = "微软雅黑";
descriptionParagraph.Range.Font.Size = 12;
descriptionParagraph.SpaceAfter = 15;
// 添加产品特性列表
AddProductFeatures(document, product.Features);
// 添加价格信息
var priceParagraph = document.AddParagraph(document.Content.End - 1,
$"价格: ¥{product.Price.ToString("N2")}");
priceParagraph.Range.Font.Name = "微软雅黑";
priceParagraph.Range.Font.Size = 16;
priceParagraph.Range.Font.Bold = 1;
priceParagraph.Range.Font.Color = WdColor.wdColorRed;
priceParagraph.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
}
/// <summary>
/// 添加产品特性列表
/// </summary>
/// <param name="document">文档对象</param>
/// <param name="features">特性列表</param>
private void AddProductFeatures(IWordDocument document, List<string> features)
{
// 添加标题
var featuresTitle = document.AddParagraph(document.Content.End - 1, "产品特性:");
featuresTitle.Range.Font.Bold = 1;
featuresTitle.SpaceAfter = 10;
// 添加特性列表
foreach (var feature in features)
{
var featureParagraph = document.AddParagraph(document.Content.End - 1, "• " + feature);
featureParagraph.Range.Font.Name = "微软雅黑";
featureParagraph.Range.Font.Size = 11;
featureParagraph.FirstLineIndent = -20; // 负缩进以对齐项目符号
featureParagraph.LeftIndent = 20;
featureParagraph.SpaceAfter = 5;
}
// 添加空行
document.AddParagraph(document.Content.End - 1);
}
}
/// <summary>
/// 产品信息模型
/// </summary>
public class Product
{
/// <summary>
/// 产品名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 产品描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 产品特性列表
/// </summary>
public List<string> Features { get; set; }
/// <summary>
/// 产品价格
/// </summary>
public decimal Price { get; set; }
/// <summary>
/// 产品图片路径
/// </summary>
public string ImagePath { get; set; }
}
实战案例:创建员工信息表
现在,让我们通过一个完整的示例来综合运用所学知识,创建一个包含多种结构化元素的员工信息表。
using MudTools.OfficeInterop;
using MudTools.OfficeInterop.Word;
using System;
public class EmployeeInfoReportGenerator
{
/// <summary>
/// 生成员工信息报告
/// </summary>
public void GenerateEmployeeReport()
{
try
{
// 创建新的Word文档
using var wordApp = WordFactory.BlankWorkbook();
var document = wordApp.ActiveDocument;
wordApp.Visibility = WordAppVisibility.Hidden;
wordApp.DisplayAlerts = WdAlertLevel.wdAlertsNone;
// 设置文档页面布局
document.PageSetup.Orientation = WdOrientation.wdOrientPortrait;
document.PageSetup.TopMargin = 72; // 1英寸 = 72磅
document.PageSetup.BottomMargin = 72;
document.PageSetup.LeftMargin = 72;
document.PageSetup.RightMargin = 72;
// 添加标题
var titleParagraph = document.AddParagraph(0, "员工信息报告");
titleParagraph.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
titleParagraph.Range.Font.Name = "微软雅黑";
titleParagraph.Range.Font.Size = 20;
titleParagraph.Range.Font.Bold = 1;
// 添加空行
document.AddParagraph(document.Content.End - 1);
// 添加报告日期
var dateParagraph = document.AddParagraph(document.Content.End - 1, $"生成日期: {DateTime.Now:yyyy年MM月dd日}");
dateParagraph.Alignment = WdParagraphAlignment.wdAlignParagraphRight;
dateParagraph.Range.Font.Size = 12;
// 添加空行
document.AddParagraph(document.Content.End - 1);
document.AddParagraph(document.Content.End - 1);
// 创建员工信息表格
var tableRange = document.Content;
tableRange.Collapse(WdCollapseDirection.wdCollapseEnd);
var table = document.Tables.Add(tableRange, 6, 5); // 5行数据+1行标题
// 设置表格标题行
string[] headers = { "员工编号", "姓名", "部门", "职位", "入职日期" };
for (int i = 1; i <= headers.Length; i++)
{
var cell = table.Cell(1, i);
cell.Range.Text = headers[i - 1];
cell.Range.Font.Bold = 1;
cell.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
cell.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
}
// 填充表格数据
string[,] employeeData = {
{"E001", "张三", "技术部", "高级软件工程师", "2020-03-15"},
{"E002", "李四", "市场部", "市场经理", "2019-07-22"},
{"E003", "王五", "人事部", "人事专员", "2021-01-10"},
{"E004", "赵六", "财务部", "财务主管", "2018-11-05"},
{"E005", "钱七", "技术部", "前端开发工程师", "2022-02-28"}
};
for (int i = 0; i < employeeData.GetLength(0); i++)
{
for (int j = 0; j < employeeData.GetLength(1); j++)
{
var cell = table.Cell(i + 2, j + 1);
cell.Range.Text = employeeData[i, j];
cell.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
cell.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
}
}
// 设置表格样式
table.Borders.Enable = 1;
table.Borders.LineStyle = WdLineStyle.wdLineStyleSingle;
table.Borders.LineWidth = WdLineWidth.wdLineWidth100pt;
table.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent;
table.PreferredWidth = 100;
// 调整列宽
table.Columns[1].PreferredWidth = 15; // 员工编号列
table.Columns[2].PreferredWidth = 20; // 姓名列
table.Columns[3].PreferredWidth = 20; // 部门列
table.Columns[4].PreferredWidth = 25; // 职位列
table.Columns[5].PreferredWidth = 20; // 入职日期列
// 添加总结段落
document.AddParagraph(document.Content.End - 1);
var summaryParagraph = document.AddParagraph(document.Content.End - 1,
$"本报告共包含 {employeeData.GetLength(0)} 名员工的信息。所有数据均为最新更新。");
summaryParagraph.Alignment = WdParagraphAlignment.wdAlignParagraphLeft;
summaryParagraph.FirstLineIndent = 21; // 首行缩进
summaryParagraph.SpaceBefore = 12;
summaryParagraph.SpaceAfter = 12;
// 插入公司Logo(如果存在)
try
{
if (System.IO.File.Exists(@"C:\Images\company_logo.png"))
{
document.AddParagraph(document.Content.End - 1);
var logoRange = document.Content;
logoRange.Collapse(WdCollapseDirection.wdCollapseEnd);
var logoShape = document.InlineShapes.AddPicture(@"C:\Images\company_logo.png", false, true);
logoShape.Width = 120;
logoShape.Height = 60;
logoRange.InsertAfter("\n");
}
}
catch (Exception ex)
{
Console.WriteLine($"插入Logo时发生错误: {ex.Message}");
}
// 保存文档
string outputPath = $@"C:\Reports\EmployeeReport_{DateTime.Now:yyyyMMdd}.docx";
document.SaveAs(outputPath, WdSaveFormat.wdFormatXMLDocument);
document.Close();
Console.WriteLine($"员工信息报告已生成: {outputPath}");
}
catch (Exception ex)
{
Console.WriteLine($"生成员工信息报告时发生错误: {ex.Message}");
}
}
}
// 使用示例
class Program
{
static void Main(string[] args)
{
var generator = new EmployeeInfoReportGenerator();
generator.GenerateEmployeeReport();
}
}
总结
本文详细介绍了如何使用MudTools.OfficeInterop.Word库操作Word文档中的结构化元素,包括:
-
段落与节操作:学习了如何遍历文档中的所有段落,以及如何使用节为文档的不同部分设置不同的页面布局。
-
表格自动化:掌握了创建表格、填充数据、设置样式和边框,以及合并拆分单元格等操作。
-
图片与形状插入:了解了内嵌形状和浮动形状的区别,以及如何插入图片并设置其属性。
通过实战案例,我们综合运用了这些知识点,创建了一个完整的员工信息报告。这些技能对于开发文档自动化系统、报告生成工具等应用具有重要意义。
在下一篇文章中,我们将学习Word文档的页面设置与打印控制技巧,包括设置纸张大小、方向、页边距等高级功能,敬请期待!

浙公网安备 33010602011771号