C#程序通过模板自动创建Word文档

简介: 原文:C#程序通过模板自动创建Word文档引言:这段时间有项目要用到c#生成Word文档,通过网络查找到很多内容,但是功能上满足不了个人需求,于是决定借助网友们已经写好的代码,加以修改完善,以便于更好的交流和以后相似问题可以迅速的解决! 备注:本文用到的相关文件,在日志结尾提供下载 ? 第...
原文: C#程序通过模板自动创建Word文档

引言:这段时间有项目要用到c#生成Word文档,通过网络查找到很多内容,但是功能上满足不了个人需求,于是决定借助网友们已经写好的代码,加以修改完善,以便于更好的交流和以后相似问题可以迅速的解决!

备注:本文用到的相关文件,在日志结尾提供下载

?

第一步、项目基础——引用的添加

01??

02

03

注意:此处要查找的“Microsoft.Office.Interop.Word.dll”版本必须为“11.*.*.*”,“*”代表数字

第二步、代码的编写

按照个人编程习惯,先编写又满足程序功能需求的详细的类,在主程序中通过调用这个类的方法实现功能。(一次编写多次实现)

我把这个类定义为Report,下面是我用到的Report类代码,仅供参考,并没有详尽的备注和错误处理,若是您直接使用我的代码,出现的问题可以恢复本日志或者Q我,空间有我的联系方式:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Office.Interop.Word;
?
namespace TravelAgencyApplication  // 根据自己需要修改命名空间
{
    class Report
    {
        private _Application wordApp = null;
        private _Document wordDoc = null;
        public _Application Application
        {
            get
            {
                return wordApp;
            }
            set
            {
                wordApp = value;
            }
        }
        public _Document Document
        {
            get
            {
                return wordDoc;
            }
            set
            {
                wordDoc = value;
            }
        }
?
        // 通过模板创建新文档
        public void CreateNewDocument(string filePath)
        {
            try
            {
                killWinWordProcess();
                wordApp = new ApplicationClass();
                wordApp.DisplayAlerts = WdAlertLevel.wdAlertsNone;
                wordApp.Visible = false;
                object missing = System.Reflection.Missing.Value;
                object templateName = filePath;
                wordDoc = wordApp.Documents.Open(ref templateName, ref missing,
                    ref missing, ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
        }
?
        // 保存新文件
        public void SaveDocument(string filePath)
        {
            object fileName = filePath;
            object format = WdSaveFormat.wdFormatDocument;//保存格式
            object miss = System.Reflection.Missing.Value;
            wordDoc.SaveAs(ref fileName, ref format, ref miss,
                ref miss, ref miss, ref miss, ref miss,
                ref miss, ref miss, ref miss, ref miss,
                ref miss, ref miss, ref miss, ref miss,
                ref miss);
            //关闭wordDoc,wordApp对象
            object SaveChanges = WdSaveOptions.wdSaveChanges;
            object OriginalFormat = WdOriginalFormat.wdOriginalDocumentFormat;
            object RouteDocument = false;
            wordDoc.Close(ref SaveChanges, ref OriginalFormat, ref RouteDocument);
            wordApp.Quit(ref SaveChanges, ref OriginalFormat, ref RouteDocument);
        }
?
        // 在书签处插入值
        public bool InsertValue(string bookmark, string value)
        {
            object bkObj = bookmark;
            if (wordApp.ActiveDocument.Bookmarks.Exists(bookmark))
            {
                wordApp.ActiveDocument.Bookmarks.get_Item(ref bkObj).Select();
                wordApp.Selection.TypeText(value);
                return true;
            }
            return false;
        }
?
        // 插入表格,bookmark书签
        public Table InsertTable(string bookmark, int rows, int columns, float width)
        {
            object miss = System.Reflection.Missing.Value;
            object oStart = bookmark;
            Range range = wordDoc.Bookmarks.get_Item(ref oStart).Range;//表格插入位置
            Table newTable = wordDoc.Tables.Add(range, rows, columns, ref miss, ref miss);
            //设置表的格式
            newTable.Borders.Enable = 1;  //允许有边框,默认没有边框(为0时报错,1为实线边框,2、3为虚线边框,以后的数字没试过)
            newTable.Borders.OutsideLineWidth = WdLineWidth.wdLineWidth050pt;//边框宽度
            if (width != 0)
            {
                newTable.PreferredWidth = width;//表格宽度
            }
            newTable.AllowPageBreaks = false; 
            return newTable;
        }
?
?
        // 合并单元格 表id,开始行号,开始列号,结束行号,结束列号
        public void MergeCell(int n, int row1, int column1, int row2, int column2)
        {
            wordDoc.Content.Tables[n].Cell(row1, column1).Merge(wordDoc.Content.Tables[n].Cell(row2, column2));
        }
?
        // 合并单元格 表名,开始行号,开始列号,结束行号,结束列号
        public void MergeCell(Microsoft.Office.Interop.Word.Table table, int row1, int column1, int row2, int column2)
        {
            table.Cell(row1, column1).Merge(table.Cell(row2, column2));
        }
?
        // 设置表格内容对齐方式 Align水平方向,Vertical垂直方向(左对齐,居中对齐,右对齐分别对应Align和Vertical的值为-1,0,1)Microsoft.Office.Interop.Word.Table table
        public void SetParagraph_Table(int n, int Align, int Vertical)
        {
            switch (Align)
            {
                case -1: wordDoc.Content.Tables[n].Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphLeft; break;//左对齐
                case 0: wordDoc.Content.Tables[n].Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter; break;//水平居中
                case 1: wordDoc.Content.Tables[n].Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphRight; break;//右对齐
            }
            switch (Vertical)
            {
                case -1: wordDoc.Content.Tables[n].Range.Cells.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalTop; break;//顶端对齐
                case 0: wordDoc.Content.Tables[n].Range.Cells.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter; break;//垂直居中
                case 1: wordDoc.Content.Tables[n].Range.Cells.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalBottom; break;//底端对齐
            }
        }
?
        // 设置单元格内容对齐方式
        public void SetParagraph_Table(int n, int row, int column, int Align, int Vertical)
        {
            switch (Align)
            {
                case -1: wordDoc.Content.Tables[n].Cell(row, column).Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphLeft; break;//左对齐
                case 0: wordDoc.Content.Tables[n].Cell(row, column).Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter; break;//水平居中
                case 1: wordDoc.Content.Tables[n].Cell(row, column).Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphRight; break;//右对齐
            }
            switch (Vertical)
            {
                case -1: wordDoc.Content.Tables[n].Cell(row, column).Range.Cells.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalTop; break;//顶端对齐
                case 0: wordDoc.Content.Tables[n].Cell(row, column).Range.Cells.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter; break;//垂直居中
                case 1: wordDoc.Content.Tables[n].Cell(row, column).Range.Cells.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalBottom; break;//底端对齐
            }
            
        }
?
?
        // 设置表格字体
        public void SetFont_Table(Microsoft.Office.Interop.Word.Table table, string fontName, double size)
        {
            if (size != 0)
            {
                table.Range.Font.Size = Convert.ToSingle(size);
            }
            if (fontName != "")
            {
                table.Range.Font.Name = fontName;
            }
        }
        
        // 设置单元格字体
        public void SetFont_Table(int n, int row, int column, string fontName, double size,int bold)
        {
            if (size != 0)
            {
                wordDoc.Content.Tables[n].Cell(row, column).Range.Font.Size = Convert.ToSingle(size);
            }
            if (fontName != "")
            {
                wordDoc.Content.Tables[n].Cell(row, column).Range.Font.Name = fontName;
            }
                wordDoc.Content.Tables[n].Cell(row, column).Range.Font.Bold = bold;// 0 表示不是粗体,其他值都是
        }
        
        // 是否使用边框,n表格的序号,use是或否
        // 该处边框参数可以用int代替bool可以让方法更全面
        // 具体值方法中介绍
        public void UseBorder(int n,bool use)
        {
            if (use)
            {
                wordDoc.Content.Tables[n].Borders.Enable = 1; 
                //允许有边框,默认没有边框(为0时无边框,1为实线边框,2、3为虚线边框,以后的数字没试过)
            }
            else
            {
                wordDoc.Content.Tables[n].Borders.Enable = 0;
            }
        }
?
        // 给表格插入一行,n表格的序号从1开始记
        public void AddRow(int n)
        {
            object miss = System.Reflection.Missing.Value;
            wordDoc.Content.Tables[n].Rows.Add(ref miss);
        }
?
        // 给表格添加一行
        public void AddRow(Microsoft.Office.Interop.Word.Table table)
        {
            object miss = System.Reflection.Missing.Value;
            table.Rows.Add(ref miss);
        }
?
        // 给表格插入rows行,n为表格的序号
        public void AddRow(int n, int rows)
        {
            object miss = System.Reflection.Missing.Value;
            Microsoft.Office.Interop.Word.Table table = wordDoc.Content.Tables[n];
            for (int i = 0; i < rows; i++)
            {
                table.Rows.Add(ref miss);
            }
        }
?
        // 删除表格第rows行,n为表格的序号
        public void DeleteRow(int n, int row)
        {
            Microsoft.Office.Interop.Word.Table table = wordDoc.Content.Tables[n];
            table.Rows[row].Delete();
        }
?
        // 给表格中单元格插入元素,table所在表格,row行号,column列号,value插入的元素
        public void InsertCell(Microsoft.Office.Interop.Word.Table table, int row, int column, string value)
        {
            table.Cell(row, column).Range.Text = value;
        }
?
        // 给表格中单元格插入元素,n表格的序号从1开始记,row行号,column列号,value插入的元素
        public void InsertCell(int n, int row, int column, string value)
        {
            wordDoc.Content.Tables[n].Cell(row, column).Range.Text = value;
        }
?
        // 给表格插入一行数据,n为表格的序号,row行号,columns列数,values插入的值
        public void InsertCell(int n, int row, int columns, string[] values)
        {
            Microsoft.Office.Interop.Word.Table table = wordDoc.Content.Tables[n];
            for (int i = 0; i < columns; i++)
            {
                table.Cell(row, i + 1).Range.Text = values[i];
            }
        }
?
        // 插入图片
        public void InsertPicture(string bookmark, string picturePath, float width, float hight)
        {
            object miss = System.Reflection.Missing.Value;
            object oStart = bookmark;
            Object linkToFile = false;       //图片是否为外部链接
            Object saveWithDocument = true;  //图片是否随文档一起保存 
            object range = wordDoc.Bookmarks.get_Item(ref oStart).Range;//图片插入位置
            wordDoc.InlineShapes.AddPicture(picturePath, ref linkToFile, ref saveWithDocument, ref range);
            wordDoc.Application.ActiveDocument.InlineShapes[1].Width = width;   //设置图片宽度
            wordDoc.Application.ActiveDocument.InlineShapes[1].Height = hight;  //设置图片高度
        }
?
        // 插入一段文字,text为文字内容
        public void InsertText(string bookmark, string text)
        {
            object oStart = bookmark;
            object range = wordDoc.Bookmarks.get_Item(ref oStart).Range;
            Paragraph wp = wordDoc.Content.Paragraphs.Add(ref range);
            wp.Format.SpaceBefore = 6;
            wp.Range.Text = text;
            wp.Format.SpaceAfter = 24;
            wp.Range.InsertParagraphAfter();
            wordDoc.Paragraphs.Last.Range.Text = "\n";
        }
?
        // 杀掉winword.exe进程
        public void killWinWordProcess()
        {
            System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("WINWORD");
            foreach (System.Diagnostics.Process process in processes)
            {
                bool b = process.MainWindowTitle == "";
                if (process.MainWindowTitle == "")
                {
                    process.Kill();
                }
            }
        }
    }
}

?

我在项目中的具体调用的片段代码:

Report report = new Report();
report.CreateNewDocument(Application.StartupPath + "\\地接社.doc"); //模板路径
report.InsertValue("djs_name", this.comboBox_djs_name.Text);
report.InsertValue("djs_man", this.comboBox_djs_man.Text);
report.InsertValue("djs_num", this.textBox_djs_num.Text);
report.InsertValue("djs_tel", this.textBox_djs_tel.Text);
report.InsertValue("djs_fax", this.textBox_djs_fax.Text);
report.InsertValue("zts_name", this.comboBox_zts_name.Text);
report.InsertValue("zts_man", this.comboBox_zts_man.Text);
report.InsertValue("zts_num", this.textBox_zts_num.Text);
report.InsertValue("zts_tel", this.textBox_zts_tel.Text);
report.InsertValue("zts_fax", this.textBox_zts_fax.Text);
report.InsertValue("行程", this.textBoxXC.Text);
int xx = Int32.Parse(this.comboBoxdays.Text);
report.AddRow(1, xx);
for (int i = 0; i < xx;i++ )
{
    string sss="";
    if (up[i].checkBoxZ.Checked||up[i].checkBoxSDZ.Checked||up[i].checkBoxHZ.Checked)
        sss += "早";
    if (up[i].checkBoxZH.Checked||up[i].checkBoxSDZH.Checked||up[i].checkBoxSDZHB.Checked)
        sss += "中";
    if (up[i].checkBoxW.Checked||up[i].checkBoxSDW.Checked)
        sss += "晚";
    string bzz = "";
    if (up[i].textBoxS.Text.Trim() == "早餐后,")
    { }
    else { bzz += up[i].textBoxS.Text; }
    if (up[i].textBoxX.Text.Trim() == "午餐后,")
    { }
    else { bzz += up[i].textBoxX.Text; }
    string rq = "";
    if (!this.cbb.Checked)
        rq = up[i].labelDayNo.Text + "\n" + up[i].dateTimePicker.Text + "\n" + up[i].labelWeek.Text;
    else
        rq = up[i].labelDayNo.Text;
    string[] values ={ rq,bzz,sss, up[i].comboBoxAdd.Text};
    report.InsertCell(1, 7+i, 4, values);
}
int deletei = 0 ;
for (int i = xx-1; i >=0; i--)
{
    if (up[i].textBoxS.Text.Trim() == "早餐后," && up[i].textBoxX.Text.Trim() == "午餐后,")
    {
        report.DeleteRow(1, i + 7);
        deletei++;
    }
}
xx = xx - deletei;
report.AddRow(1,1);
report.MergeCell(1, 7 + xx, 3, 7 + xx, 4); //合并单元格 表名,开始行号,开始列号,结束行号,结束列号
string[] values1 ={"项 目","分  项  报  价","小计"};
report.InsertCell(1, 7 + xx, 3, values1);
report.AddRow(1, 9);
string[] sd1 = { "门  票", this.textBoxMP.Text, this.textBoxMPF.Text +"元/人  " };
string[] sd2 = { "住  宿", this.comboBox_zs_bz.Text + "  " + this.textBoxZSAJ.Text, this.textBoxZSF.Text+"元/人  " };
string[] sd00 = { "住  宿备  注", this.textBox10.Text};
string[] sd3 = { "餐  费", this.textBoxCF.Text, this.textBoxCFZ.Text+"元/人  " };
string[] sd4 = { "车  费", this.comboBoxCF.Text, this.textBoxCFJG.Text+"元/辆  " };
string[] sd5 = { "火  车", this.textBox3.Text, this.textBox4.Text+"元/人  " };
string[] sd6 = { "导  服", this.textBoxD.Text, this.textBoxDF.Text + "元/团  " };
string[] sd12 = { "陪  同住  宿", this.textBoxPS.Text, this.textBox5.Text + "元/团  " };
report.InsertCell(1, 8 + xx, 3, sd1);
report.InsertCell(1, 9 + xx, 3, sd2);
report.MergeCell(1, 10 + xx, 2, 10 + xx, 3);
report.InsertCell(1, 10 + xx, 2, sd00);
report.InsertCell(1, 11 + xx, 3, sd3);
report.InsertCell(1, 12 + xx, 3, sd4);
report.InsertCell(1, 13 + xx, 3, sd5);
report.InsertCell(1, 14 + xx, 3, sd6);
report.InsertCell(1, 15 + xx, 3, sd12);
report.MergeCell(1, 16 + xx, 2, 16 + xx, 3); //表名,开始行号,开始列号,结束行号,结束列号
report.AddRow(1, 3);
string[] sd7 = { "合 计", this.textBoxHJ.Text };
string[] sd9 = { "自 理项 目", this.textBoxZFXM.Text };
string[] sd10 = { "购 物点", this.textBoxGWD.Text };
string[] sd11 = { "备 注", this.textBox7.Text };
report.InsertCell(1, 16 + xx, 2, sd7);
report.InsertCell(1, 17 + xx, 2, sd9);
report.InsertCell(1, 18 + xx, 2, sd10);
report.InsertCell(1, 19 + xx, 2, sd11);
report.UseBorder(1,iss);
report.SetParagraph_Table(1, 16 + xx, 2, -1, 0);
report.SetParagraph_Table(1, 17 + xx, 2, -1, 0);
report.SetParagraph_Table(1, 18 + xx, 2, -1, 0);
report.SetParagraph_Table(1, 19 + xx, 2, -1, 0);
report.SetParagraph_Table(1, 10 + xx, 2, -1, 0);
report.SetFont_Table(1, 16 + xx, 1, "宋体", 14,1);
report.SetFont_Table(1, 17 + xx, 1, "宋体", 14,1);
report.SetFont_Table(1, 18 + xx, 1, "宋体", 14,1);
report.SetFont_Table(1, 19 + xx, 1, "宋体", 14,1);
report.SetFont_Table(1, 16 + xx, 2, "宋体", 12,1);
report.SetFont_Table(1, 7 + xx, 1, "宋体", 14, 1);
report.SetFont_Table(1, 7 + xx, 2, "宋体", 14, 1);
report.SetFont_Table(1, 7 + xx, 3, "宋体", 14, 1);
report.SetParagraph_Table(1, 7 + xx, 2, 0, 0);
report.SaveDocument(file);

我是使用一半模板一般代码的方式导出的:

直接上图:

04

05 06

相关文件下载:

1.Microsoft.Office.Interop.Word多版本压缩包

目录
相关文章
|
XML 前端开发 C#
C#编程实践:解析HTML文档并执行元素匹配
通过上述步骤,可以在C#中有效地解析HTML文档并执行元素匹配。HtmlAgilityPack提供了一个强大而灵活的工具集,可以处理各种HTML解析任务。
496 19
|
缓存 C# Windows
C#程序如何编译成Native代码
【10月更文挑战第15天】在C#中,可以通过.NET Native和第三方工具(如Ngen.exe)将程序编译成Native代码,以提升性能和启动速度。.NET Native适用于UWP应用,而Ngen.exe则通过预编译托管程序集为本地机器代码来加速启动。不过,这些方法也可能增加编译时间和部署复杂度。
1058 2
|
存储 SQL 数据库连接
C#程序调用Sql Server存储过程异常处理:调用存储过程后不返回、不抛异常的解决方案
本文分析了C#程序操作Sql Server数据库时偶发的不返回、不抛异常问题,并提出了解决思路。首先解析了一个执行存储过程的函数`ExecuteProcedure`,其功能是调用存储过程并返回影响行数。针对代码执行被阻塞但无异常的情况,文章总结了可能原因,如死锁、无限循环或网络问题等。随后提供了多种解决方案:1) 增加日志定位问题;2) 使用异步操作提升响应性;3) 设置超时机制避免阻塞;4) 利用线程池分离主线程;5) 通过信号量同步线程;6) 监控数据库连接状态确保可用性。这些方法可有效应对数据库操作中的潜在问题,保障程序稳定性。
1047 11
|
存储 安全 Java
程序与技术分享:C#值类型和引用类型的区别
程序与技术分享:C#值类型和引用类型的区别
439 0
|
算法 Java 测试技术
Benchmark.NET:让 C# 测试程序性能变得既酷又简单
Benchmark.NET是一款专为 .NET 平台设计的性能基准测试框架,它可以帮助你测量代码的执行时间、内存使用情况等性能指标。它就像是你代码的 "健身教练",帮助你找到瓶颈,优化性能,让你的应用跑得更快、更稳!希望这个小教程能让你在追求高性能的路上越走越远,享受编程带来的无限乐趣!
1215 13
|
XML C# 开发工具
C# 删除Word文档中的段落
【11月更文挑战第3天】本文介绍了两种方法来操作 Word 文档:一是使用 `Microsoft.Office.Interop.Word` 库,适用于 Windows 环境下操作 Word 文档,需引用相应库并在代码中引入命名空间;二是使用 Open XML SDK,适用于处理 .docx 格式的文档,通过引用 `DocumentFormat.OpenXml` 库实现。文中提供了示例代码,展示了如何打开、删除段落并保存文档。
483 5
|
安全 API C#
C# 如何让程序后台进程不被Windows任务管理器强制结束
C# 如何让程序后台进程不被Windows任务管理器强制结束
1110 0
|
API C#
C#实现Winform程序右下角弹窗消息提示
C#实现Winform程序右下角弹窗消息提示
1261 1
|
C# 容器
C#中的命名空间与程序集管理
在C#编程中,`命名空间`和`程序集`是组织代码的关键概念,有助于提高代码的可维护性和复用性。本文从基础入手,详细解释了命名空间的逻辑组织方式及其基本语法,展示了如何使用`using`指令访问其他命名空间中的类型,并提供了常见问题的解决方案。接着介绍了程序集这一.NET框架的基本单位,包括其创建、引用及高级特性如强名称和延迟加载等。通过具体示例,展示了如何创建和使用自定义程序集,并提出了针对版本不匹配和性能问题的有效策略。理解并善用这些概念,能显著提升开发效率和代码质量。
707 4