C# 读取多条数据记录导出到 Word 标签模板

简介: C# 读取多条数据记录导出到 Word 标签模板

应用需求

数据库数据表中的数据输出并打印,WORD 是一个良好的载体, 在应用项目里,许多情况下我们会使用数据记录结合 WORD 标签模板进行配合,输出数据进行打印的功能需求。

实现步骤

1、设计WORD模板,在需要输出值的地方设置 自定义关键字+字段名(如%%_name),其中%%_为自定义关键字,name为输出字段名。

2、根据条件查询数据表,生成 DataSet ,如果有数据则取 Tables[0]里的数据记录。

3、拷贝 WORD 全部内容到剪贴板做模板数据。

4、遍历数据表记录,粘贴剪贴板内容, 按照自定义关键+列名称,在 WORD 中按关键字查找,并替换成对应的实际数据,完成输出。

举例我们需要提取人员的基本信息生成准考证并打印如下图:

根据以上的结果输出,我们需要设置如下图标签模板:

如图我们准备SQL语句如:select ProjectName,Name,Sex,IdCard,EACode,Position,Time,Address from infos where ... 并生成数据表。

其中 “ key_” 则为自定义关键字,后缀则对应查询输出字段名。

范例运行环境

操作系统: Windows Server 2019 DataCenter

操作系统上安装 Office Word 2016

数据库:Microsoft SQL Server 2016

.net版本: .netFramework4.7.1 或以上

开发工具:VS2019  C#

配置Office DCOM

配置方法可参照我的文章《C# 读取Word表格到DataSet》进行处理和配置。

实现代码

组件库引入

核心代码

public string DataTableToWord(string _filename,string _repeatKey,object _dataset),该方法提供3个参数,WORD模板文件名、自定义关键字、System.Data.DataSet。

public void DataTableToWord(string _filename,string _repeatKey,object _dataset)
        {
            Object Nothing = System.Reflection.Missing.Value;
            object filename = _filename;
            //创建一个名为WordApp的组件对象
            Word.Application WordApp = new Word.Application();
            //创建一个名为WordDoc的文档对象
            WordApp.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
 
            Word.Document WordDoc = WordApp.Documents.Open(ref filename, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing);
 
            WordDoc.SpellingChecked = false;//关闭拼写检查
 
            WordDoc.ShowSpellingErrors = false;//关闭显示拼写错误提示框
 
        WordApp.Selection.WholeStory();
        WordApp.Selection.Cut();
        DataSet ds=(DataSet)_dataset;
        System.Data.DataTable  dt=ds.Tables[0];
        for(int i=0;i<dt.Rows.Count;i++)
        {
          WordApp.Selection.Paste();
          for(int j=0;j<dt.Columns.Count;j++)
          {
            
            string _repKey=_repeatKey+dt.Columns[j].ColumnName.ToString();
            string _repValue=string.Format("{0}",dt.Rows[i][j].ToString());
 
            bool isPhoto=false;
            if(dt.Columns[j].DataType==typeof(System.Byte[]))
            {
              isPhoto=true;
              _repValue="";
            }
 
 
            
            WordApp.Options.ReplaceSelection=true;
            Word.Find fnd = WordApp.Selection.Find;
            fnd.ClearFormatting();
 
            Object findText = _repKey;
            Object matchCase = false;
            Object matchWholeWord = Type.Missing;
            Object matchWildcards = false;
            Object matchSoundsLike = false;
            Object matchAllWordForms = false;
            Object forward = true;
            Object wrap =Word.WdFindWrap.wdFindContinue;
            Object format = false;
            Object replaceWith ="";
            Object replace =Type.Missing;;
            Object matchKashida = Type.Missing;
            Object matchDiacritics = Type.Missing;
            Object matchAlefHamza = Type.Missing;
            Object matchControl = Type.Missing;
 
            
            
            while(fnd.Execute(ref findText, ref matchCase, ref matchWholeWord,ref matchWildcards, ref matchSoundsLike, ref matchAllWordForms, 
              ref forward, ref wrap, ref format, ref replaceWith,ref replace, ref matchKashida, ref matchDiacritics,ref matchAlefHamza, ref matchControl))
            {
 
              string r_f=WordApp.Selection.Font.Name.ToString();
              
                
              WordApp.Selection.Range.Text=_repValue;
              if(isPhoto==true)
              {
                string _jpgfile=_path+System.Guid.NewGuid()+".jpg";
                                if (dt.Rows[i][j] == System.DBNull.Value)
                                {
                                    continue;
                                }
                byte[] filedata = (byte[])dt.Rows[i][j];
                System.IO.MemoryStream ms = new MemoryStream(filedata);
                System.Drawing.Image img1 = System.Drawing.Image.FromStream(ms);
                img1.Save(@_jpgfile);
                ms.Close();
                object m1=Type.Missing;
                object m2=Type.Missing;
                object m3=Type.Missing;
                                
                Word.InlineShape pic= WordApp.Selection.InlineShapes.AddPicture(@_jpgfile,ref m1,ref m2,ref m3);
                int def_width=240;
                int def_height=320;
                foreach(Word.Bookmark bm in  WordApp.ActiveDocument.Bookmarks)
                {
                  string _findkey=_repKey+"_";
                  int _f1=bm.Name.IndexOf(_findkey);
                  if(_f1==0 && bm.Name.Length>(_findkey.Length))
                  {
                    string[] _paras=bm.Name.Substring(_findkey.Length,bm.Name.Length-_findkey.Length).Split('_');
                    if(_paras.GetLength(0)>1){
                      def_width=int.Parse(_paras[0]); 
                      def_height=int.Parse(_paras[1]);  
                    }
                  }
                }
                pic.Width=def_width;
                pic.Height=def_height;
//                _repValue=string.Format("{0},{1},{2},{3},{4}",_p1,_p2,_p3,def_width,def_height);
                File.Delete(@_jpgfile);
              }
          
            }
          }
          
          object dummy = System.Reflection.Missing.Value;
          object what = Word.WdGoToItem.wdGoToLine;
          object which = Word.WdGoToDirection.wdGoToLast;
          object count = System.Reflection.Missing.Value;
//          WordApp.Selection.GoTo(ref oGoToItem, ref oGoToLast, ref Nothing, ref Nothing);
          WordApp.Selection.GoTo(ref what, ref which, ref count, ref dummy);
          //default 表示每行记录之间插入分页符,最后一行时不再插入分页符,以免造成多余一空白页
            if(i!=dt.Rows.Count-1)
            {
              object ib = Word.WdBreakType.wdPageBreak; 
              WordApp.Selection.InsertBreak(ref ib);
            }
          }
  
             }
      WordDoc.Save();
            WordDoc.Close(ref Nothing, ref Nothing, ref Nothing);
      //关闭WordApp组件对象
      WordApp.Quit(ref Nothing, ref Nothing, ref Nothing);
 
}

小结

1、核心代码中有对字段类型的判断:if(dt.Columns[j].DataType==typeof(System.Byte[])),如果为System.Byte[],则表示为图片类型字段,这是我们自行的约定,对于图片的宽高可以根据实际需要进行设定或定义参数。

2、在根据模板内容,每输出一条记录后,均会插入分页符:

object ib = Word.WdBreakType.wdPageBreak;

WordApp.Selection.InsertBreak(ref ib);

以保证打印的数据区域独立和完整性,这要根据实际应用来决定是否输出。

这些代码我们提供了一些操作WORD相关的关键方法,这里仅作参考,欢迎大家评论指教!

相关文章
|
5天前
|
开发框架 .NET Java
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
27 11
|
6天前
|
开发框架 .NET Java
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
37 10
|
2月前
|
XML C# 开发工具
C# 删除Word文档中的段落
【11月更文挑战第3天】本文介绍了两种方法来操作 Word 文档:一是使用 `Microsoft.Office.Interop.Word` 库,适用于 Windows 环境下操作 Word 文档,需引用相应库并在代码中引入命名空间;二是使用 Open XML SDK,适用于处理 .docx 格式的文档,通过引用 `DocumentFormat.OpenXml` 库实现。文中提供了示例代码,展示了如何打开、删除段落并保存文档。
|
3月前
|
SQL 缓存 分布式计算
C#如何处理上亿级数据的查询效率
C#如何处理上亿级数据的查询效率
49 1
|
3月前
|
中间件 数据库连接 API
C#数据分表核心代码
C#数据分表核心代码
47 0
|
3月前
|
XML JSON 前端开发
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
655 0
|
2月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
42 3
|
13天前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
61 12
|
2月前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
68 4
|
4月前
|
API C#
C# 一分钟浅谈:文件系统编程
在软件开发中,文件系统操作至关重要。本文将带你快速掌握C#中文件系统编程的基础知识,涵盖基本概念、常见问题及解决方法。文章详细介绍了`System.IO`命名空间下的关键类库,并通过示例代码展示了路径处理、异常处理、并发访问等技巧,还提供了异步API和流压缩等高级技巧,帮助你写出更健壮的代码。
56 2