C#使用模板文件批量导出word文档

需求背景

        因为疫情爆发,进入一级响应状态,公安部门进行了严格出入境管理,需要对每个出入境的人进行状态跟踪。

        疫情专班会将出入境的每个人员汇总在一张Excel表中,如下图所示:

 

 

         每一行对应一个人员信息,一个人员信息需要生成一个协查函,需要将人员信息填入到固定格式的协查函中,协查函的格式如下图所示:

 


功能实现 

        功能实现分成两个部分,一是从Excel读取数据,二是将读取的数据批量输出到Word文档。

从Excel读取数据使用NPOI,输出到word文档使用Microsoft Word Object Library.

NPOI可以在NuGet程序包中搜索到:

 Microsoft Word Object Library.可以在类库中引用到。

 考虑到速度,功能用winform程序实现。


 实现效果

启动程序时:

选择Excel:

导入Excel:

 导出到Word:

打开Word看看:

 

 在开发之前需要对创建一个Word(dot格式)模板文件,内容格式很协查函一样,然后再需要插入数据的地方设置书签即可。

 


 程序代码

ExcelHelp类用于将选中的Excel数据导入到datatable中。

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace WindowsFormsApp1
{public class ExcelHelp{/// <summary>/// 根据指定流文件将Excel导入到datatable中/// </summary>public virtual DataTable ExcelExportDataTable(){DataTable dt = new DataTable();OpenFileDialog fileDialog = new OpenFileDialog();fileDialog.Filter = "Excel文件|*.xls;*.xlsx";fileDialog.InitialDirectory = "E:\\";//设置默认打开路径if (fileDialog.ShowDialog() == DialogResult.OK){string fileName = fileDialog.FileName;//得到文件所在位置FileStream fs = new FileStream(fileDialog.FileName, FileMode.Open, FileAccess.Read);dt = ExcelToDataTable(fs, 0, 2);}return dt;}/// <summary>/// 将excel数据流中的数据转化为datatable/// </summary>/// <param name="ExcelFileStream">指定流文件</param>/// <param name="SheetIndex">导入sheet页页号</param>/// <param name="HeaderRowIndex">行标题行号</param>/// <returns></returns>private DataTable ExcelToDataTable(Stream ExcelFileStream, int SheetIndex, int HeaderRowIndex){//HSSFWorkbook workbook = new HSSFWorkbook(ExcelFileStream);//IWorkbook workbook = new HSSFWorkbook(ExcelFileStream);IWorkbook workbook = new XSSFWorkbook(ExcelFileStream);ISheet sheet = workbook.GetSheetAt(SheetIndex);DataTable table = new DataTable();/*手动构建列名*/IRow headerRow = sheet.GetRow(HeaderRowIndex);int cellCount = headerRow.LastCellNum;DataColumn columnNo = new DataColumn("No");table.Columns.Add(columnNo);DataColumn columnName = new DataColumn("Name");//姓名table.Columns.Add(columnName);DataColumn columnID = new DataColumn("ID");//身份证table.Columns.Add(columnID);DataColumn columnPhone = new DataColumn("Phone");//电话table.Columns.Add(columnPhone);DataColumn columnStreet = new DataColumn("Street");//电话table.Columns.Add(columnStreet);DataColumn columnXVillage = new DataColumn("XVillage");//行政村table.Columns.Add(columnXVillage);DataColumn columnZVillage = new DataColumn("ZVillage");//自然村table.Columns.Add(columnZVillage);DataColumn columnAddress = new DataColumn("Address");//具体地址table.Columns.Add(columnAddress);DataColumn columnDutyName = new DataColumn("DutyName");//责任人姓名table.Columns.Add(columnDutyName);DataColumn columnDutyPhone = new DataColumn("DutyPhone");//责任人电话table.Columns.Add(columnDutyPhone);DataColumn columnStatus = new DataColumn("Status");//管控状态table.Columns.Add(columnStatus);DataColumn columnBackTime = new DataColumn("BackTime");//返回封锁区时间table.Columns.Add(columnBackTime);DataColumn columnProvince = new DataColumn("Province");//省table.Columns.Add(columnProvince);DataColumn columnCity = new DataColumn("City");//市table.Columns.Add(columnCity);DataColumn columnCountry = new DataColumn("Country");//村table.Columns.Add(columnCountry);DataColumn columnAddress2 = new DataColumn("Address2");//具体地址table.Columns.Add(columnAddress2);/*构建datatable表体*/int firstRowNum = 3;//int rowCount = sheet.LastRowNum;for (int i = firstRowNum; i <= sheet.LastRowNum; i++){IRow row = sheet.GetRow(i);DataRow dataRow = table.NewRow();for (int j = row.FirstCellNum; j < cellCount; j++){if (row.GetCell(j) != null){dataRow[j] = row.GetCell(j).ToString();}}table.Rows.Add(dataRow);}ExcelFileStream.Close();workbook = null;sheet = null;return table;}}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Office.Interop.Word;namespace WindowsFormsApp1
{public partial class Form1 : Form{public System.Data.DataTable table;public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){ExcelHelp eh = new ExcelHelp();table = eh.ExcelExportDataTable();dataGridView1.AllowUserToAddRows = false;dataGridView1.DataSource = table;if (table.Rows.Count == 0){MessageBox.Show("Excel中无数据!");return;}}private void button2_Click(object sender, EventArgs e){if (table == null){MessageBox.Show("请先选择Excel!");return;}int count = table.Rows.Count;//Microsoft.Office.Interop.Word._Application oWord;if (count > 0){for (int i = 0; i < count; i++){//创建一个Word应用程序实例Microsoft.Office.Interop.Word._Application oWord = new Microsoft.Office.Interop.Word.Application();object oMissing = System.Reflection.Missing.Value;//设置为不可见oWord.Visible = false;//模板文件地址,debug bin 目录下//object oTemplate = "E://template.dot";object oTemplate = System.Windows.Forms.Application.StartupPath + "\\template.dot";//以模板为基础生成文档Microsoft.Office.Interop.Word._Document oDoc = oWord.Documents.Add(ref oTemplate, ref oMissing, ref oMissing, ref oMissing);//声明书签数组object[] oBookMark = new object[8];//赋值书签名oBookMark[0] = "Name";oBookMark[1] = "ID";oBookMark[2] = "Phone";oBookMark[3] = "City";oBookMark[4] = "Country";oBookMark[5] = "Address2";oBookMark[6] = "MM";oBookMark[7] = "DD";//赋值数据到书签的位置string mm = DateTime.Now.Month.ToString();string dd = DateTime.Now.Day.ToString();oDoc.Bookmarks.get_Item(ref oBookMark[0]).Range.Text = table.Rows[i]["Name"].ToString();oDoc.Bookmarks.get_Item(ref oBookMark[1]).Range.Text = table.Rows[i]["ID"].ToString();oDoc.Bookmarks.get_Item(ref oBookMark[2]).Range.Text = table.Rows[i]["Phone"].ToString();oDoc.Bookmarks.get_Item(ref oBookMark[3]).Range.Text = table.Rows[i]["City"].ToString();oDoc.Bookmarks.get_Item(ref oBookMark[4]).Range.Text = table.Rows[i]["Country"].ToString();oDoc.Bookmarks.get_Item(ref oBookMark[5]).Range.Text = table.Rows[i]["Address2"].ToString();oDoc.Bookmarks.get_Item(ref oBookMark[6]).Range.Text = mm;oDoc.Bookmarks.get_Item(ref oBookMark[7]).Range.Text = dd;//导出的Word文件地址设置在 debug bin里的NewFile文件夹object path = System.Windows.Forms.Application.StartupPath + "\\NewFile\\" + filename + ".doc";oDoc.SaveAs(ref path, ref oMissing, ref oMissing, ref oMissing,ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,ref oMissing, ref oMissing);oDoc.Close(ref oMissing, ref oMissing, ref oMissing);//关闭word模板oWord.Quit(ref oMissing, ref oMissing, ref oMissing);}MessageBox.Show("导出成功,生成了" + count + "个文件!");}else{MessageBox.Show("Excel中无数据!");}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548359.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WP7 开发(九) WP7控件开发(六)-DeepZoom技术

2011年11月14日 -DeepZoom&#xff1a;源于遥感影像的金字塔显示方式&#xff0c;提供了与高分辨率图像进行交互的能力&#xff0c;可以快速缩放图像而不影响应用的性能&#xff0c;加载或平移图像时可以光滑过度 -应用&#xff1a;高分辨率、极大图像的浏览&#xff0c;3D合成…

以太网单播、组播、广播

单播&#xff1a;单播MAC地址是从源到目的的唯一地址。 广播&#xff1a;就是一个主机向所有主机发送一个数据包。 组播&#xff1a;就是把数据发送给一组主机或者发送给感兴趣的主机。&#xff08;组播的MAC地址是以&#xff1a;01-00-5E开头的&#xff0c;组播的IP地址224.0.…

[Android疑难杂症]Gallery默认和横竖屏切换选中状态问题(2.3、2.3系统存在)

前言Gallery的Item使用的是一个ImageViewTextView&#xff0c;并且为其设置了selector&#xff0c;当使用setSelection设置时、横竖屏切换时Item的状态不会改变&#xff0c;这个目前在2.2、2.3系统中存在&#xff0c;高版本如4.0是不存在的。声明欢迎转载&#xff0c;但请保留文…

原子操作的实现原理(锁和循环CAS)

1 引言 原子&#xff08;atom&#xff09;本意是“不能被进一步分割的最小粒子”&#xff0c;而原子操作&#xff08;atomic operation&#xff09;意为”不可被中断的一个或一系列操作” 。在多处理器上实现原子操作就变得有点复杂。本文让我们一起来聊一聊在Inter处理器和…

git常规命令大全

git remote show origin 显示远端信息 git push --mirror 迁移的服务器路径&#xff08;ssh&#xff09; git remote add origin ssh 地址 git push -u origin 分支名 git push origin :分支名 删除远程分支 git push origin --delete 删除远程分支 1&#xff09;配置使用git仓…

const 一级指针的启示

直接上代码: #include int main() { const char* ptr nullptr;//可以通过二级指针去修改 //const chartemp_str &ptr; //*temp_str “123”; const chartemp_str nullptr; temp_str &ptr; *temp_str “123”; std::string str; str.resize(3); //memcpy(&…

Linux之软件安装YUM

在终端中输入yum即可…… 如果已经安装&#xff0c;会显示yum的参数 如果没有安装&#xff0c;会提示yum未安装或无效命令…… 建议&#xff1a; 以Redhat Enterprise Linux 5&#xff08;RHEL 5&#xff09;为例&#xff1a; 1. 首先你可以使用命令&#xff1a;rpm -qa |grep …

java(安全方便的从控制台读入数据)[对Scanner类进行封装,用正则表达式判断]...

此版本是对自己的这篇博客中的源码进行了优化&#xff1a;http://blog.csdn.net/haifengzhilian/article/details/7835404 package com.iflytek.util; import java.util.*; import java.util.regex.Pattern;/*** 类名&#xff1a;GetSafeInput* 作用&#xff1a;在控制台中安全…

关于子网的网络地址和广播地址的计算问题的方法

关于子网的网络地址和广播地址的计算问题的方法 前言 近期在备考网络管理员考试&#xff0c;发现之前学习的知识有些遗忘&#xff0c;更新一下自己的博客记录一下学习的过程&#xff0c;今天先写一个小问题的计算方法&#xff0c;希望可以对大家有所帮助。 一、题目&#xf…

cdgb调试linux崩溃程序

直接上原图: 使用命令:cgdb test test.core.2235 安装cgdb程序步骤&#xff1a; 1&#xff1a;wget http://cgdb.me/files/cgdb-0.7.1.tar.gz(网络会受到影响) 2:解压.tar.gz文件 3:./configure --prefix/usr/local之后会提示 error: CGDB requires curses.h or ncurses/cu…

关于计算机网络中超网聚合问题的计算

关于计算机网络中超网聚合问题的计算 近期备战网络管理员考试&#xff0c;遇到了一类的超网聚合问题&#xff0c;觉得有点意思&#xff0c;写一下解题步骤。 题目 把4个网络133.24.12.0/24&#xff0c;133.24.13.0/24&#xff0c;133.24.14.0/24和133.24.15.0/24汇聚成一个超…

博客

http://cocoalit.com/index?cat46

软考网络管理员存储容量计算相关问题

软考网络管理员存储容量计算相关问题 题目&#xff1a; 内存按字节编址&#xff0c;用存储容量为8K * 8比特的存储器芯片构成地址编号7000H至EFFFH的内存空间&#xff0c;至少需要多少片内存&#xff1f; 解题过程&#xff1a; 首先求解总体地址容量&#xff1a; 总体容量E…

hMailServer 邮件系统安装配置篇

此篇进入正题&#xff0c;详细的说一下安装和配置过程。得先说一下&#xff0c;hMailServer是真正的邮件服务端&#xff0c;而Roundcube Webmail仅仅是为hMailServer提供Webmail应用的&#xff0c;可以让你通过Web方式收发邮件&#xff0c;如果你不用Web方式收发邮件&#xff0…

linux下生成coredump文件

1产生core文件方法 产生coredump的条件&#xff0c;首先需要确认当前会话的ulimit –c&#xff0c;若为0&#xff0c;则不会产生对应的coredump&#xff0c;需要进行修改和设置。 ulimit -c unlimited (可以产生coredump且不受大小限制)&#xff0c;这种设置仅对当前生效&…

关于选择排序的优化——同时找出最小值与最大值

关于选择排序的优化——同时找出最小值与最大值 近期在学习排序算法&#xff0c;第一种方法就是选择排序。首先选择排序是一种不稳定的算法&#xff0c;其思想是通过遍历数组&#xff0c;找出最小值&#xff08;最大值&#xff09;的位置&#xff0c;放到已排序序列的启示&…

《几何与代数导引》例2.9

求以直线$xyz$为轴&#xff0c;过直线$2x3y-5z$的圆锥面方程.解&#xff1a;两条直线显然相交于原点.设圆锥面上的任意一点为$(x,y,z)$.我们知道直线$2x3y-5z$的方向向量为$(15,10,-6)$.则直线$xyz$的方向向量为$(1,1,1)$.我们知道\begin{equation}\cos \langle (1,1,1), (15,1…

std::make_unique和 std::make_shared区别

区别1&#xff1a;分配除的指针&#xff0c;前者是不能赋值&#xff0c;只能move,后者可以赋值 区别2&#xff1a;前者使用智能指针数组&#xff0c;后者不行&#xff08;因为后者分配出来的指针具有单一性&#xff09; #include #include class A { public: A() { std::c…

win8学习--------File

//创建文件 using namespace Windows::Storage; MainPage^ rootPage;rootPage MainPage::Current; create_task(KnownFolders::DocumentsLibrary->CreateFileAsync(rootPage->Filename, CreationCollisionOption::ReplaceExisting)).then([this](StorageFile^ file){ro…

centos下升级g++版本

转载请注明文章出处&#xff1a;https://juejin.im/post/5d0ef5376fb9a07ef63fe74e CentOS 7官方源带的gcc最新版本是4.8.5&#xff0c;发布于2015年&#xff0c;年代久远且不支持c14。要编译c14及以上项目&#xff0c;必须要升级现有版本或者安装高版本的gcc。&#xff08;yu…