C#自动更新Excel报表而不改变原有样式 2021.8.11

  • 1、需求分析
    • 1.1 原始数据表(`原始数据.xlsx`)
    • 1.2 Excel报表(`20210811 报表.xlsx`)
    • 1.3 报表更新内容(复制粘贴后的效果)
  • 2、目标实现
    • 2.1 Excel文件类型分析(xls和xlsx)
    • 2.2 C# 解决Excel报表自动更新
      • 2.2.1 C#环境配置(VS2010+C#)
      • 2.2.2 新建C#项目
      • 2.2.3 编写C#代码
      • 2.2.4 运行结果
      • 2.2.5 总结

1、需求分析

在日常的工作和学习生活中,很多单位需要进行统计分析生成Excel报表,报表文件是一个汇总性的文件,它的格式一般来说相对固定,而工作人员需要做的就是整理汇总,这个过程当中通常需要利用其它来源的原始数据表,也就是说需要将各方的Excel表格中的数据按照对应关系更新到指定的Excel报表文件中,如果采用传统的人工复制的方式则效率低下,可能会出错,工作量大;而此时则可以利用编程语言来提高办公的数据处理自动化效率并提高准确率,工作人员可将原来复制粘贴数据的时间用来检验数据是否更新正确,可以极大地缩短工作时间从而得心应手。

1.1 原始数据表(原始数据.xlsx

温度 湿度

原始数据表Excel中包含 温度湿度 两个表,这两个表的结构相同,第一列都是站点点号第二列和第三列则是相邻两天的监测数据

1.2 Excel报表(20210811 报表.xlsx

Excel报表中包含四个表,由于表中的点号往往不一定和原始数据中的点号相对应,同时天气原因会导致原始数据中的部分点号可能会观测不到数据,因此需要以原始数据为参考对这四个表中的昨天温度(湿度)和今天温度(湿度)两列数据按照站点号进行快速有效的更新。

温度1-20 温度21-39
湿度1-20 湿度21-39

1.3 报表更新内容(复制粘贴后的效果)

由于这里原始数据中的点号顺序和报表中要更新的点号顺序一致,所以传统复制粘贴的方式能够采用,但这种方式效率低下,在数据量大且点号顺序不一致时面临极大的不确定性和不准确性,当然非要使用复制粘贴也不是不可以,需要在原始数据表中按照更新报表中的站点号顺序来用宏筛选赋值后即可操作(主要利用IF、IFERROR和VLOOKUP三个函数,如:IF(IFERROR(VLOOKUP(A317,A23:G310,6,0),NA()),IFERROR(VLOOKUP(A1,A23:G310,6,0),NA()),NA())

温度1-20 更新后 温度21-39 更新后
湿度1-20 更新后 湿度21-39 更新后

2、目标实现

2.1 Excel文件类型分析(xls和xlsx)

这里利用C#编程语言实现对Excel数据的操作,其中主要包含读取Excel数据和写入Excel数据,而常见的Excel数据格式包含.xlsx.xls.csv等,这里主要操作的是xls和xlsx类型的Excel数据表。
        xls和xlsx的区别主要包含三个方面:

  • (1)文件格式不同

    • xls 是一个特有的二进制格式,其核心结构是复合文档类型的结构
    • 而xlsx 的核心结构是 XML 类型的结构,采用的是基于 XML 的压缩方式,使其占用的空间更小。xlsx 中最后一个 x 的意义就在于此。
  • (2)版本不同
    • xls是Excel 2003及以前版本生成的文件格式
    • 而xlsx是Excel 2007及以后版本生成的文件格式
  • (3)兼容性不同
    • xls 就是 Microsoft Excel 工作表,是一种非常常用的电子表格格式。xls文件可以使用Microsoft Excel打开,使用Microsoft Excel可以将XLS格式的表格转换为多种格式:XML表格、XML数据、网页、使用制表符分割的文本文件(.txt)、使用逗号分隔的文本文件(.csv)等。
    • xlsx是Microsoft Office Excel 2007/2010/2013/2016/2019文档的扩展名, xlsx格式是向下兼容的,可兼容xls格式,xlsx是从Office 2007开始使用的,是用新的基于XML的压缩文件格式取代了其目前专有的默认文件格式,在传统的文件名扩展名后面添加了字母x(即:docx取代doc、.xlsx取代xls等等),使其占用空间更小。

2.2 C# 解决Excel报表自动更新

C# 是微软公司发布的一种由CC++衍生出来的面向对象的编程语言、运行于 .NET Framework.NET Core (完全开源,跨平台)之上的高级程序设计语言。

  1. C#是由C和C++衍生出来的一种安全的、稳定的、简单的、优雅的面向对象编程语言。它在继承C和C++强大功能的同时去掉了一些它们的复杂特性(例如没有以及不允许多重继承)。
  2. C#是面向对象的编程语言。它使得程序员可以快速地编写各种基于MICROSOFT .NET平台的应用程序,MICROSOFT .NET提供了一系列的工具和服务来最大程度地开发利用计算与通讯领域。
  3. C#使得C++程序员可以高效的开发程序,且因可调用由 C/C++ 编写的本机原生函数,而绝不损失C/C++原有的强大的功能。因为这种继承关系,C#与C/C++具有极大的相似性,熟悉类似语言的开发者可以很快的转向C#。

2.2.1 C#环境配置(VS2010+C#)

首先参考微软官方帮助安装 Visual Studio来安装Microsoft Visual Studio,安装过程中记得选择编程语言C#(默认就是C#),安装完成即可,这里选择的是VS 2010版本,当然自己可以选择VS 2015VS 2017VS 2019均可。


2.2.2 新建C#项目

第一步,打开VS 2010,新建项目选择Visual C#中的Windows窗体应用程序,之后输入项目名称点击确定。

        第二步,为了能够在C#Windows窗体应用程序中操作Excel,需要添加Excel引用,点击菜单栏中的项目->添加引用,在弹出的添加引用窗口中选择.NET中的Microsoft.Office.Interop.Excel后点击确定即可在右侧的解决方案资源管理器项目下的引用中看到是否添加进来。




        第三步,在解决方案院管理器中双击Form1.cs进入Form1窗体,利用左侧的工具箱向窗体中添加控件(5个Label标签、3个TextBox文本框、4个Button按钮、1个DataGridView数据网格视图、1个TabControl切换、1个StatusStrip状态栏和1个Timer定时器),窗体最终设计好的结果如下图所示。

2.2.3 编写C#代码

C# .NET直接通过Excel接口来处理数据报表更新问题,只需在From1.cs中编写相应的功能代码。
                Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;namespace UpdateBaoBiaoExcelByAnatherExcel
{public partial class Form1 : Form{public Microsoft.Office.Interop.Excel.Application excelApp;public System.Data.DataTable dt;public int index = 1;public Form1(){this.StartPosition = FormStartPosition.CenterScreen;InitializeComponent();AllocConsole();Console.SetWindowPosition(0, 0);Console.WriteLine("欢迎使用 Excel数据文件自动更新报表系统 v1.0!");}[DllImport("kernel32.dll")]static extern bool FreeConsole();//调用系统API,释放用控制台窗口[DllImport("kernel32.dll")]public static extern bool AllocConsole();//调用系统API,调用控制台窗口private void button1_Click(object sender, EventArgs e){this.label4.Visible = false;this.label5.Visible = false;this.tabControl1.Visible = false;this.dataGridView1.Visible = false;OpenFileDialog dialog = new OpenFileDialog();dialog.Multiselect = true;//该值确定是否可以选择多个文件dialog.Title = "请选择Excel数据文件";dialog.Filter = "Excel文件(*.xls,*.xlsx)|*.xls;*.xlsx";if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK){this.textBox1.Text = dialog.FileName;}}private void button2_Click(object sender, EventArgs e){this.label4.Visible = false;this.label5.Visible = false;this.tabControl1.Visible = false;this.dataGridView1.Visible = false;OpenFileDialog dialog = new OpenFileDialog();dialog.Multiselect = true;//该值确定是否可以选择多个文件dialog.Title = "请选择Excel报表文件";dialog.Filter = "Excel文件(*.xls,*.xlsx)|*.xls;*.xlsx";if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK){this.textBox2.Text = dialog.FileName;}}private void button4_Click(object sender, EventArgs e){this.Close();FreeConsole();System.Windows.Forms.Application.Exit();}private void button3_Click(object sender, EventArgs e){try{if (this.textBox1.Text == ""){MessageBox.Show("请选择Excel数据文件!");return;}if (this.textBox3.Text == ""){MessageBox.Show("请输入数据文件保存数据的sheet名!");return;}if (this.textBox2.Text == ""){MessageBox.Show("请选择要更新的Excel报表!");return;}excelApp = new Microsoft.Office.Interop.Excel.Application();loadXls(this.textBox1.Text, this.textBox3.Text);Console.ForegroundColor = ConsoleColor.Green;for (int i = 0; i < dt.Rows.Count; i++){for (int j = 0; j < dt.Columns.Count; j++){Console.Write(dt.Rows[i][j] + " ");}Console.WriteLine();}writeToXls(this.textBox2.Text, dt, this.textBox3.Text);this.label4.Visible = true;this.label5.Visible = true;this.tabControl1.Visible = true;this.dataGridView1.Visible = true;this.dataGridView1.DataSource = dt;Console.WriteLine("Finished");MessageBox.Show("Success!");}catch (Exception ex){MessageBox.Show(ex.Message);}finally{excelApp.Quit();System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);}}public void loadXls(string path,string sheetName){try{dt = new System.Data.DataTable(sheetName);dt.Columns.Add("站点号", Type.GetType("System.String"));dt.Columns.Add("昨天数据", Type.GetType("System.String"));dt.Columns.Add("今天数据", Type.GetType("System.String"));Workbook workBook = excelApp.Workbooks.Open(path);for (int sheeti = 1; sheeti <= workBook.Worksheets.Count; sheeti++){if (workBook.Worksheets[sheeti].Name.Contains(sheetName)){Worksheet workSheet = workBook.Worksheets[sheeti];var usedRange = workSheet.UsedRange;var rowCount = usedRange.Rows.Count;var colCount = usedRange.Columns.Count;int start_point_row = 2, end_point_row = rowCount, start_point_col = colCount - 1, end_point_col = colCount;for (int i = start_point_row; i <= end_point_row; ++i){DataRow dr = dt.NewRow();String yesterday_data = workSheet.UsedRange.Cells[i, start_point_col].Value == null ? null : String.Format("{0:F}", workSheet.UsedRange.Cells[i, start_point_col].Value);String today_data = workSheet.UsedRange.Cells[i, end_point_col].Value == null ? null : String.Format("{0:F}", workSheet.UsedRange.Cells[i, end_point_col].Value);dr["站点号"] = workSheet.UsedRange.Cells[i, 1].Value;dr["昨天数据"] = yesterday_data;dr["今天数据"] = today_data;dt.Rows.Add(dr);}break;}}workBook.Close();}catch (Exception ex){MessageBox.Show(ex.Message);}}public void writeToXls(string path, System.Data.DataTable dt,string sheetname){try{Console.ForegroundColor = ConsoleColor.Cyan;Workbook workBook = excelApp.Workbooks.Open(path);int workSheetNum = 1;for (; workSheetNum <= workBook.Worksheets.Count; workSheetNum++){if (workBook.Worksheets[workSheetNum].Name.Contains(sheetname)){Worksheet workSheet = workBook.Worksheets[workSheetNum];System.Data.DataTable dt_sheet = new System.Data.DataTable(workSheet.Name);dt_sheet.Columns.Add("站点号", Type.GetType("System.String"));dt_sheet.Columns.Add("昨天数据", Type.GetType("System.String"));dt_sheet.Columns.Add("今天数据", Type.GetType("System.String"));Console.WriteLine("*********修改报表中名字为" + workSheet.Name + " 的sheet内容如下:***********");var rowCount = workSheet.UsedRange.Rows.Count;int start_point_row = 1, end_point_row = 1;for (int i = 1; i <= rowCount; i++)//先从第一列找点号{if (workSheet.UsedRange.Cells[i, 1].Value == "站点号"){start_point_row = i + 1;}if (workSheet.UsedRange.Cells[i, 1].Value == "结论:"){end_point_row = i; break;}}for (int i = start_point_row; i <= end_point_row; ++i){String pid = workSheet.UsedRange.Cells[i, 1].Value == null ? null : String.Format("{0}", workSheet.UsedRange.Cells[i, 1].Value);int k = 0;for (; k < dt.Rows.Count; k++){String dt_pid = Convert.ToString(dt.Rows[k][0]);if (dt_pid == pid){if (dt.Rows[k][1] != null)workSheet.Cells[i + 1, 3].Value = dt.Rows[k][1];if (dt.Rows[k][2] != null)workSheet.Cells[i + 1, 4].Value = dt.Rows[k][2];Console.WriteLine(dt.Rows[k][0] + "   " + dt.Rows[k][1] +"   "+ dt.Rows[k][2]);String yesterday_data = workSheet.UsedRange.Cells[i, 3].Value == null ? null : String.Format("{0:F}", workSheet.UsedRange.Cells[i, 3].Value);String today_data = workSheet.UsedRange.Cells[i, 4].Value == null ? null : String.Format("{0:F}", workSheet.UsedRange.Cells[i, 4].Value);DataRow dr_sheet = dt_sheet.NewRow();dr_sheet["站点号"] = workSheet.UsedRange.Cells[i, 1].Value;dr_sheet["昨天数据"] = yesterday_data;dr_sheet["今天数据"] = today_data;dt_sheet.Rows.Add(dr_sheet);break;}}}TabPage Page = new TabPage();Page.Name = workSheet.Name;Page.Text = workSheet.Name;Page.TabIndex = index++;Page.SuspendLayout();DataGridView grid = new DataGridView();grid.DataSource = dt_sheet;grid.ScrollBars = System.Windows.Forms.ScrollBars.Both;System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle = new System.Windows.Forms.DataGridViewCellStyle();grid.AllowUserToAddRows = false;grid.AllowUserToDeleteRows = false;grid.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;grid.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle;grid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;dataGridViewCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;dataGridViewCellStyle.BackColor = System.Drawing.SystemColors.Control;dataGridViewCellStyle.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));dataGridViewCellStyle.ForeColor = System.Drawing.SystemColors.WindowText;dataGridViewCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;dataGridViewCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;dataGridViewCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.True;grid.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle;grid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;Page.Controls.Add(grid);Page.ResumeLayout();Page.Refresh();this.tabControl1.Controls.Add(Page);}}workBook.Save();workBook.Close();}catch (Exception ex){MessageBox.Show(ex.Message);}}private void Form1_Load(object sender, EventArgs e){this.timer1.Interval = 1000;this.timer1.Start();}private void timer1_Tick(object sender, EventArgs e){this.toolStripStatusLabel1.Text = "您好,欢迎使用本系统!" + "当前时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");}}
}

2.2.4 运行结果

原始数据文件原始数据.xlsx和要更新的Excel报表文件20210811 报表.xlsx

        最后点击菜单栏下调试中的开始执行不调试)即可启动运行,运行界面如下图所示,其中左侧命令行窗口为日志窗口,右侧为程序主界面,需要选择原始数据文件和要更新的报表文件,同时输入数据表名后点击确定即可。(注:项目功能为将原始数据Excel文件中指定表中的数据更新到报表Excel文件中相关联的表中

报表温度1-20 更新结果 报表温度21-39 更新结果
报表湿度1-20 更新结果 报表中湿度21-39 更新结果

2.2.5 总结

由于C#操作Excel读写数据时调用的是微软Microsoft下办公软件Office下的Excel接口,因此采用C#代码进行的操作本质上等同于人工手动打开Excel应用来操作数据,从而实现一定的准确性和有效性,大数据量才会使得程序耗费较长的执行时间

C#自动更新Excel报表而不改变原有样式(2021.8.11)相关推荐

  1. python自动汇总表格_用Python自动生成Excel报表

    作者 / 来源:林骥(ID:linjiwx) 01 安装和导入模块 以 Python 中的 openpyxl 模块为例,它能够读取和修改 Excel 文件,如果你还没有安装,可以通过以下命令进行安装: ...

  2. 用Python自动生成Excel报表

    在日常工作中,可能会有一些重复无聊的任务,比如说,从 Excel 或数据库中收集一些数据,设置相应的数据格式并做成报表. 类似这种重复无聊的任务,我们完全可以交给 Python 去自动完成,只要第一次 ...

  3. 【定制开发】【M11】Python采集数据源,自动生成Excel报表:避免人力浪费,提高工作效率

    目录 一.背景 二.采集数据源 2.采集[氮氨]数据 3.采集[COD 化学需氧量]数据 4.采集[总氮]数据 三.输出Excel内容样式 1.输出文件命名格式 2.文件内容格式详述 四.解决方案 1 ...

  4. python自动生成excel报表

    1.将SQL语句查询的内容,直接写入到excel报表中,以下为全部脚本.要求:此版本必须运维在windows平台,并且安装了excel程序,excel版本不限. python版本为2.7 if b 判 ...

  5. 9中继器添加一列序号自增_三个动态自动更新EXCEL序号的小技巧,解决重复编号困扰...

    本文将涉及:1.序列--常用的有等比和等差,可结合步长,对序列号编制进行定义2.ROW()--返回当前单元格所在行号3.SUBTOTAL()--条件汇总,分为忽略隐藏汇总及全部汇总的方式 通常制作一张 ...

  6. 实时更新:TIOBE世界编程语言排行榜(2021年11月份)

    内容导航: 1.TIOBE排行榜 2.总榜(2021年11月份) 3.本月前三名 3.1.Python 3.2.C 3.3.Java 4.学习路线图 5.参考地址 1.TIOBE排行榜 TIOBE排行 ...

  7. oracle生成excle报表,oracle自动生成excel报表(时间为变量,条件含变量)

    目的:unix+oracle下每日生成前一天某统计报表,以一张统计表为例. ----在unix下执行sh脚本---- sqlplus -s username/password < @/home/ ...

  8. 批量生成带超链接目录且自动更新 Excel

    文章目录 自动生成带超链接的目录 一.知识点 get.workbook宏表函数使用 INDEX() FIND() REPLACE() HYPERLINK() 二.举例 第一步:定义名称 第二步:提取所 ...

  9. easyui数据表格重置_Python办公自动化,自动更新表格,告别繁琐

    大家好,又到了Python办公自动化专题 . 今天我们讲解的案例是如何使用Python自动更新Excel表格,简单来说就 是 每天都会对Excel中多个sheet进行更新,需要操作完后可以用程序完成第 ...

最新文章

  1. vue 设置输入法隐藏_原来iPhone自带的输入法这么强大?好多人都不知道其中的隐藏功能...
  2. 人月神话——焦油坑 《读后感》
  3. python整数类型在每一台计算机上的取值范围是一样的_第四章、Python数据类型
  4. 好程序员三期Android高端班开班典礼-乱世看我称雄
  5. C++20 - 下一个大版本功能确定
  6. JavaScript精要
  7. Python jsonpath库的使用:解析json并将结果保存到文件
  8. 肝了十几个小时的java反射,希望对大家有所帮助吧!
  9. C++Eratosthenes埃氏筛法获取素数列表的实现算法(附完整源码)
  10. 利用Photoshop减小照片景深
  11. tif 高程_使用ArcGIS提取高程点
  12. 矩池云安装gcc4.9和g++4.9简单教程
  13. 加载字典文件,扫描网站潜在目录
  14. ETL工具-Kettle Spoon教程
  15. PIL+pyqt 写了一个图片批量无损压缩工具python
  16. 中亦安图通过创业板注册:年营收近12亿 拟募资6亿
  17. JDK8的介绍下载和安装(附网盘地址)
  18. SM2263XT贴四片PF29F01T2ANCTH2,SM2263XT量产工具成功开卡
  19. Task02——支持向量机(Support Vector Machine,SVM)
  20. Java是用来干什么的?

热门文章

  1. 女大学生: 4年de 同居大学生活后 还剩什么~!~ 感
  2. 已知函数的分布,如何使用metropolis 算法去得到目标样本函数
  3. MAC远程连接Windows的远程桌面Microsoft Remote Desktop工具下载
  4. 网络管理、ssh、日志管理、归档和文件传输、rpm
  5. Unity 事件番外篇:事件管理中心(另一种版本)
  6. Sugar-Electron 基于Electron的轻量级开发框架
  7. Fidder Everywhere 下载和安装教程
  8. 英德谋定红茶产业-农业大健康·李喜贵:功能性农业品牌之路2021-03-02
  9. linux格式化分区提示正在被使用,Linux系统格式化分区时提示Could not start /dev怎么办?...
  10. Redis基础知识入门