C# 读取二维数组集合输出到Word预设表格

目录

应用场景

设计约定

范例运行环境

[配置Office DCOM](#配置Office DCOM)

实现代码

组件库引入

核心代码

DataSet转二维数组

导出写入WORD表格

调用举例

小结


应用场景

存储或导出个人WORD版简历是招聘应用系统中的常用功能,我们通常会通过应用系统采集用户的个人简历信息到数据库,许多情况下我们会读取数据记录导出到WORD文件中,以便汇总、打印。其中,WORD表格元素是经常会被用到的,比如问卷调查表格、教育经历表格、工作经历表格等等。

设计约定

1、设计WORD模板,在需要输出值的地方绘制表格,表格的数量对应输出的数据表数量。

2、根据条件查询数据表,生成 DataSet ,遍历 Tables ,生成对应的二维数组集合,将数据输出到对应的WORD表格中。

3、按约定,WORD表格的数量应该大于等于 DataSet 里的 Tables 数量。

4、按参数设定对应的WORD表格ID序号,如参数设定为2,则表示输出到WORD文件中的第二个表格中。(注意:WORD表格序号以1为开始)

在输出写入的方式中,我们约定有两种方式:

一为覆盖式写入(即已预知数据输出模式)举例如下图:

二为动态式写入(即未知数据行数量)举例如下图:

范例运行环境

操作系统: Windows Server 2019 DataCenter

操作系统上安装 Office Word 2016

数据库:Microsoft SQL Server 2016

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

开发工具:VS2019 C#

配置Office DCOM

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

实现代码

组件库引入

核心代码

DataSet转二维数组

public object[,] DataSetToObjectData(DataSet ds,int TableId,bool hastitle),该方法提供3个参数,DataSet数据集、指定表索引、导出是否包含标题列名称。

cs 复制代码
		public object[,] DataSetToObjectData(DataSet ds,int TableId,bool hastitle)
		{
			ArrayList rowdata = new ArrayList();
			int _fieldcount=ds.Tables[TableId].Columns.Count;
			Object[] colvalues = new Object[_fieldcount];
			for(int i=0;i<_fieldcount;i++)
			{
				colvalues[i]=ds.Tables[TableId].Columns[i].ColumnName;
			}
			if(hastitle)
				rowdata.Add(colvalues);
			for(int i=0;i<ds.Tables[TableId].Rows.Count;i++)
			{
				Object[] values = new Object[_fieldcount];
				values=ds.Tables[TableId].Rows[i].ItemArray;
				rowdata.Add(values);
				RowsCount++;
			}
			object[,] rv=new object[rowdata.Count,_fieldcount];
			for(int i=0;i<rowdata.Count;i++)
			{
				for(int j=0;j<_fieldcount;j++)
				{
					rv[i,j]=((object[])rowdata[i])[j];
				}
			}
			return rv;
		}
导出写入WORD表格

public string DataSetToWordTables(string _filename,int[,] _drawtype,object[] _datas),该方法提供3个参数,使用的WORD模板文件路径、写入配置(包括要写入的WORD表格ID,写入方式:0为覆盖;1为从第二行动态追加;3为从第一行动态追加)、对应的二维数组集合。

cs 复制代码
public string DataSetToWordTables(string _filename,int[,] _drawtype,object[] _datas)        {
            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;//关闭显示拼写错误提示框

				for(int i=_drawtype.GetLength(0)-1;i>=0;i--)
				{
					int _tableid=_drawtype[i,0];
					int _draw=_drawtype[i,1];
					object[,] r_datas=(object[,])_datas[i];
					int _rowscount=r_datas.GetLength(0);
                    if (_rowscount == 0)
                    {
                        WordDoc.Tables[_tableid].Delete();
                        continue;
                    }
                    int startrowid = 2;
                    if (_draw == 3)
                    {
                        startrowid = 1;
                    }
					if(_draw==1||_draw==3)
					{
						object _row=(object)WordDoc.Tables[_tableid].Rows[startrowid];
						for(int j=0;j<_rowscount-1;j++)
						{
							WordDoc.Tables[_tableid].Rows.Add(ref _row);

						}
					}
                    for (int k = 0; k < r_datas.GetLength(0); k++)
					{
						for(int m=0;m<r_datas.GetLength(1);m++)
						{
                            WordDoc.Tables[_tableid].Cell(k + startrowid, m + 1).Range.Text = r_datas[k, m].ToString();
                        }
					}
				}

			WordDoc.Save();
            WordDoc.Close(ref Nothing, ref Nothing, ref Nothing);
			//关闭WordApp组件对象
			WordApp.Quit(ref Nothing, ref Nothing, ref Nothing);
    return "";
}
调用举例

如下为示例代码:

cs 复制代码
string _filename=@"x:\test.docx";
int[,] _drawtype=new int[2,2];
_drawtype[0,0]=1;  //写入WORD第一个表格
_drawtype[0,1]=0;  //覆盖式写入

_drawtype[1,0]=2;  //写入WORD第二个表格
_drawtype[1,1]=1;  //动态追加行写入

object[] _datas=new object[2];
DataSet ds=getDataSet(); //获取DataSet对象
_datas[0]=DataSetToObjectData(ds,0,false); //获取DataSet Tables[0]的二维数组数据
_datas[1]=DataSetToObjectData(ds,1,false); //获取DataSet Tables[1]的二维数组数据

string result=DataSetToWordTables(_filename,_drawtype,_datas);  //写入Word表格        

小结

1、核心代码中对无数据的表格采取了删除WORD表格的操作。

2、预设表格的优点在于所见即所得,样式设计简单化,便于理解输出,我们还可以采用关键字定位并动态添加WORD表格的形式进行输出,来实现更加复杂的样式等。

3、核心代码中输出的起始行为第2行,根据设置也可以为第1行。如果我们设计的表格比较复杂(如包括合并单元格等),则可以对 _drawtype进行改造,增加一个参数,用于指定从第几行开始进行输出。

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

相关推荐
侃侃_天下1 小时前
最终的信号类
开发语言·c++·算法
echoarts1 小时前
Rayon Rust中的数据并行库入门教程
开发语言·其他·算法·rust
Aomnitrix2 小时前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
大飞pkz2 小时前
【设计模式】C#反射实现抽象工厂模式
设计模式·c#·抽象工厂模式·c#反射·c#反射实现抽象工厂模式
每天回答3个问题2 小时前
UE5C++编译遇到MSB3073
开发语言·c++·ue5
伍哥的传说2 小时前
Vite Plugin PWA – 零配置构建现代渐进式Web应用
开发语言·前端·javascript·web app·pwa·service worker·workbox
小莞尔3 小时前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
我是菜鸟0713号3 小时前
Qt 中 OPC UA 通讯实战
开发语言·qt
JCBP_3 小时前
QT(4)
开发语言·汇编·c++·qt·算法
Brookty3 小时前
【JavaEE】线程安全-内存可见性、指令全排序
java·开发语言·后端·java-ee·线程安全·内存可见性·指令重排序