C#实现Excel模板导出和从Excel导入数据

      午休时间写了一个Demo关于Excel导入导出的简单练习

1.窗体

2.引用office命名空间

添加引用-程序集-扩展-Microsoft.Office.Interop.Excel

3.封装的ExcelHelper.cs关键类

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Data;
  4 using System.Data.OleDb;
  5 using System.IO;
  6 using System.Linq;
  7 using System.Runtime.InteropServices;
  8 using System.Text;
  9 using System.Text.RegularExpressions;
 10 using System.Windows.Forms;
 11 namespace ExcelDemo
 12 {
 13     /// <summary>
 14     /// Excel帮助类
 15     /// string column = "商品编码,商品名称,刊登单号,门店名称";
 16     /// 导入数据
 17     /// var action = new Action<string, DataTable>((str, dtExcel) =>
 18     /// {
 19     /// this.dgvData.DataSource = dtExcel;
 20     /// });
 21     /// excelHelper.ImportExcelToDataTable(this, action, "Ebay侵权下线");
 22     /// 导出模版
 23     /// string message = string.Empty;
 24     //  excelHelper.SaveExcelTemplate(column.Split(','), "Ebay侵权下线", "Ebay侵权下线", ref message);
 25     /// </summary>
 26     public class ExcelHelper
 27     {
 28         [DllImport("User32.dll", CharSet = CharSet.Auto)]
 29         public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
 30 
 31         /// <summary>
 32         /// 保存Excel模版
 33         /// </summary>
 34         /// <param name="columns">列名,例如:商品编码,商品名称,刊登单号,门店名称</param>
 35         /// <param name="FileName">文件名,例如:Ebay侵权下线</param>
 36         /// <param name="SheetName">工作表名称,例如:Ebay侵权下线</param>
 37         /// <param name="message">错误信息</param>
 38         public void SaveExcelTemplate(string[] columns, string FileName, string SheetName, ref string message)
 39         {
 40             string Filter = "Excel文件|*.csv|Excel文件|*.xls|Excel文件|*.xlsx";
 41 
 42             SaveFileDialog saveFileDialog1 = new SaveFileDialog();
 43             saveFileDialog1.DefaultExt = "csv";
 44             saveFileDialog1.FileName = FileName;
 45             saveFileDialog1.Filter = Filter;
 46             saveFileDialog1.FilterIndex = 0;
 47             saveFileDialog1.RestoreDirectory = true;
 48             saveFileDialog1.CreatePrompt = true;
 49             saveFileDialog1.Title = "Excel文件";
 50             saveFileDialog1.InitialDirectory = Directory.GetCurrentDirectory();
 51 
 52             if (saveFileDialog1.ShowDialog() != DialogResult.OK)
 53                 return;
 54 
 55             //获得文件路径
 56             string localFilePath = saveFileDialog1.FileName.ToString();
 57             if (Regex.IsMatch(localFilePath, @"\.csv$"))
 58             {
 59                 localFilePath = Regex.Replace(saveFileDialog1.FileName, @"\.csv$", "", RegexOptions.IgnoreCase) + ".csv";
 60                 File.WriteAllText(localFilePath, string.Join(",", columns), Encoding.Default);
 61             }
 62             else
 63             {
 64                 //获取文件路径,不带文件名
 65                 ArrayToExcelTemplate(columns, localFilePath, SheetName, ref message);
 66             }
 67 
 68             if (string.IsNullOrEmpty(message))
 69                 MessageBox.Show("\n\n导出完毕! ", "提示 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
 70         }
 71 
 72         /// <summary>
 73         /// 导出模版
 74         /// </summary>
 75         /// <param name="columns">列名,例如:商品编码,商品名称,刊登单号,门店名称</param>
 76         /// <param name="localFilePath">本地路径</param>
 77         /// <param name="SheetName">工作表名称,例如:Ebay侵权下线</param>
 78         /// <param name="message">错误信息</param>
 79         public void ArrayToExcelTemplate(string[] columns, string localFilePath, string SheetName, ref string message)
 80         {
 81             Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
 82             if (xlApp == null)
 83             {
 84                 message = "无法创建Excel对象,可能计算机未安装Excel!";
 85                 return;
 86             }
 87 
 88             //創建Excel對象
 89             Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;
 90             Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
 91             Microsoft.Office.Interop.Excel.Worksheet worksheet = null;
 92             if (worksheet == null) worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets.Add(Type.Missing, Type.Missing, 1, Type.Missing);
 93             Microsoft.Office.Interop.Excel.Range range = null;
 94 
 95             long totalCount = columns.Length;
 96             worksheet.Name = SheetName;//第一个sheet在Excel中显示的名称
 97             int c;
 98             c = 0;
 99             ////写入标题
100             for (int i = 0, count = columns.Length; i < count; i++)
101             {
102                 //if (string.IsNullOrEmpty(columns[i])) continue;
103                 worksheet.Cells[1, c + 1] = columns[i];
104                 range = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[1, c + 1];
105                 range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;//居中  
106                 c++;
107 
108             }
109 
110             try
111             {
112                 localFilePath = Regex.Replace(localFilePath, ".xls$|.xlsx$", "", RegexOptions.IgnoreCase);
113                 localFilePath += xlApp.Version.CompareTo("11.0") == 0 ? ".xls" : ".xlsx";
114                 workbook.SaveCopyAs(localFilePath);
115             }
116             catch (Exception ex)
117             {
118                 message = "生成Excel附件过程中出现异常,详细信息如:" + ex.ToString();
119             }
120 
121 
122             try
123             {
124                 if (xlApp != null)
125                 {
126 
127                     int lpdwProcessId;
128                     GetWindowThreadProcessId(new IntPtr(xlApp.Hwnd), out lpdwProcessId);
129                     System.Diagnostics.Process.GetProcessById(lpdwProcessId).Kill();
130                 }
131             }
132             catch (Exception ex)
133             {
134                 message = "Delete Excel Process Error:" + ex.Message;
135             }
136 
137         }
138 
139         /// <summary>
140         /// 导入Excel
141         /// </summary>
142         /// <param name="form"></param>
143         /// <param name="callback"></param>
144         public void ImportExcelToDataTable(Form form, Action<string, DataTable> callback, string SheetName = "Sheet1")
145         {
146             string Filter = "Excel文件|*.csv|Excel文件|*.xls|Excel文件|*.xlsx";
147 
148             OpenFileDialog openFileDialog1 = new OpenFileDialog();
149             openFileDialog1.Title = "Excel文件";
150             openFileDialog1.Filter = Filter;
151             openFileDialog1.ValidateNames = true;
152             openFileDialog1.CheckFileExists = true;
153             openFileDialog1.CheckPathExists = true;
154 
155             if (openFileDialog1.ShowDialog() != DialogResult.OK)
156                 return;
157 
158             var action = new Action(() =>
159             {
160                 string localFilePath = openFileDialog1.FileName;
161                 if (File.Exists(localFilePath))
162                 {
163                     string message = string.Empty;
164                     string fileExten = Path.GetExtension(localFilePath);
165 
166                     DataTable dtExcel;
167                     if (fileExten.ToLower().Contains(".csv"))
168                     {
169                         dtExcel = ImportCSVFile(localFilePath, "Table1", ref message);
170                     }
171                     else
172                     {
173                         dtExcel = ImportExcelFile(localFilePath, "Table1", SheetName, ref message);
174                     }
175 
176                     if (callback != null)
177                     {
178                         if (form.InvokeRequired)
179                         {
180                             form.Invoke(callback, message, dtExcel);
181                         }
182                         else
183                         {
184                             callback(message, dtExcel);
185                         }
186                     }
187                 }
188             });
189 
190             action.BeginInvoke(null, null);
191         }
192 
193         /// <summary>
194         /// 执行导入
195         /// </summary>
196         /// <param name="strFileName">对应文件路径</param>
197         /// <param name="typeName">返回的Table名称</param>
198         /// <param name="message">返回的错误</param>
199         /// <returns>DataTable</returns>
200         public DataTable ImportCSVFile(string strFileName, string typeName, ref string message)
201         {
202             if (string.IsNullOrEmpty(strFileName)) return null;
203 
204             string line = string.Empty;
205             string[] split = null;
206             bool isReplace;
207             int subBegion;
208             int subEnd;
209             string itemString = string.Empty;
210             string oldItemString = string.Empty;
211             DataTable table = new DataTable(typeName);
212             DataRow row = null;
213             StreamReader sr = new StreamReader(strFileName, System.Text.Encoding.Default);
214             //创建与数据源对应的数据列 
215             line = sr.ReadLine();
216             split = line.Split(',');
217             foreach (String colname in split)
218             {
219                 table.Columns.Add(colname, System.Type.GetType("System.String"));
220             }
221             //将数据填入数据表 
222             int j = 0;
223             while ((line = sr.ReadLine()) != null)
224             {
225                 subEnd = 0;
226                 subBegion = 0;
227 
228                 if (line.IndexOf('\"') > 0)
229                 {
230                     isReplace = true;
231                 }
232                 else
233                 {
234                     isReplace = false;
235                 }
236                 itemString = string.Empty;
237                 while (isReplace)
238                 {
239 
240                     subBegion = line.IndexOf('\"');
241                     subEnd = line.Length - 1;
242                     if (line.Length - 1 > subBegion)
243                     {
244                         subEnd = line.IndexOf('\"', subBegion + 1);
245                     }
246 
247                     if (subEnd - subBegion > 0)
248                     {
249                         itemString = line.Substring(subBegion, subEnd - subBegion + 1);
250                         oldItemString = itemString;
251                         itemString = itemString.Replace(',', '|').Replace("\"", string.Empty);
252                         line = line.Replace(oldItemString, itemString);
253 
254                     }
255 
256                     if (line.IndexOf('\"') == -1)
257                     {
258                         isReplace = false;
259                     }
260 
261                 }
262 
263                 j = 0;
264                 row = table.NewRow();
265                 split = line.Split(',');
266                 foreach (String colname in split)
267                 {
268                     row[j] = colname.Replace('|', ',');
269                     j++;
270                 }
271                 table.Rows.Add(row);
272             }
273             sr.Close();
274             //显示数据 
275 
276             return table;
277         }
278 
279 
280         /// <summary>
281         /// Excel执行导入
282         /// </summary>
283         /// <param name="strFileName">对应文件路径</param>
284         /// <param name="typeName">返回的Table名称</param>
285         /// <param name="message">返回的错误</param>
286         /// <returns></returns>
287         public DataTable ImportExcelFile(string strFileName, string typeName, string SheetName, ref string message)
288         {
289             if (string.IsNullOrEmpty(strFileName)) return null;
290             DataSet Exceldt;
291             Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
292             OleDbConnection con = new OleDbConnection();
293             try
294             {
295                 //OleDbDataAdapter ExcelO = new OleDbDataAdapter(selectStr, @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + strFileName + ";Extended Properties=Excel 8.0;");
296                 string ConnStr = xlApp.Version.CompareTo("11.0") == 0 ? @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + strFileName + ";Extended Properties='Excel 8.0;IMEX=1;HDR=YES;'" : @"Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='Excel 8.0;IMEX=1;HDR=YES'; Data Source=" + strFileName;
297                 con.ConnectionString = ConnStr;
298                 con.Open();
299                 DataTable dtOle = con.GetSchema("Tables");
300                 DataTableReader dtReader = new DataTableReader(dtOle);
301                 string TableName = "";
302                 while (dtReader.Read())
303                 {
304                     TableName = dtReader["Table_Name"].ToString();
305                     break;
306                 }
307                 OleDbDataAdapter excel = new OleDbDataAdapter(string.Format("select * from [" + SheetName + "$];", TableName), ConnStr);
308                 //OleDbDataAdapter excel = new OleDbDataAdapter(selectStr, @"Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='Excel 8.0;IMEX=1;HDR=YES'; Data Source=" + strFileName);
309 
310                 Exceldt = new DataSet();
311                 excel.Fill(Exceldt, typeName);
312                 return Exceldt.Tables.Count > 0 ? Exceldt.Tables[0] : null;
313             }
314             catch (OleDbException ex)
315             {
316                 message = ex.Message;
317                 return null;
318             }
319             catch (Exception ex)
320             {
321                 message = ex.Message;
322                 return null;
323             }
324             finally
325             {
326                 con.Close();
327             }
328         }
329     }
330 }

4.演示代码

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 
 10 namespace ExcelDemo
 11 {
 12     /// <summary>
 13     /// 针对Excel写的帮助模型
 14     /// </summary>
 15     public partial class Form1 : Form
 16     {
 17         #region 变量
 18         /// <summary>
 19         /// 导出模板列集合
 20         /// </summary>
 21         List<string> columnListOut = new List<string>()
 22         {
 23             "列1",
 24             "列2",
 25             "列3",
 26             "列4"
 27         };
 28 
 29         /// <summary>
 30         /// 导出模板文件名称
 31         /// </summary>
 32         string FileName = "导出模板";
 33 
 34         /// <summary>
 35         /// Excel底层页签名称
 36         /// </summary>
 37         string SheetName = "Excel页签名称";
 38 
 39         /// <summary>
 40         /// ExcelHelper实例化
 41         /// </summary>
 42         ExcelHelper excelHelper = new ExcelHelper();
 43 
 44         #endregion
 45 
 46         #region 初始化、数据加载
 47         public Form1()
 48         {
 49             InitializeComponent();
 50         }
 51         #endregion
 52 
 53         #region 控件事件
 54         /// <summary>
 55         /// 选择文件
 56         /// </summary>
 57         /// <param name="sender"></param>
 58         /// <param name="e"></param>
 59         private void btnChooseFile_Click(object sender, EventArgs e)
 60         {
 61             //对于选择文件转化的DataTable和提示信息msg的委托
 62             Action<string, DataTable> action = new Action<string, DataTable>((string str, DataTable dt) =>
 63             {
 64                 if (dt == null || dt.Rows.Count == 0)
 65                 {
 66                     MessageBox.Show("dt为空的");
 67                     return;
 68                 }
 69 
 70                 if (dt.Rows.Count > 1000)
 71                 {
 72                     MessageBox.Show("导入的数据已超过最大限制1000条");
 73                     return;
 74                 }
 75                 if (!this.columnListOut.ToArray().All(t => dt.Columns.Contains(t)))
 76                 {
 77                     MessageBox.Show("导入的数据字段不匹配");
 78                     return;
 79                 }
 80 
 81                 //获取列1的可枚举集合
 82                 IEnumerable<string> column1List = dt.Rows.Cast<DataRow>().Select(r => r["列1"].ToString());
 83 
 84                 //验证列1必须是整数切不能是负数
 85                 decimal isDecimal = 0;
 86                 foreach (var item in column1List)
 87                 {
 88                     if ((!decimal.TryParse(item, out isDecimal)) && !string.IsNullOrEmpty(item))
 89                     {
 90                         MessageBox.Show("列1必须是Decimal类型");
 91                         return;
 92                     }
 93                     if (isDecimal < 0)
 94                     {
 95                         MessageBox.Show("列1不允许是负数");
 96                         return;
 97                     }
 98                 }
 99                 dt.AcceptChanges();
100                 this.dgv.DataSource = dt;
101             });
102             this.excelHelper.ImportExcelToDataTable(this, action, this.SheetName);
103         }
104 
105         /// <summary>
106         /// 导出模板
107         /// </summary>
108         /// <param name="sender"></param>
109         /// <param name="e"></param>
110         private void btnOut_Click(object sender, EventArgs e)
111         {
112             string[] columnList = this.columnListOut.ToArray();
113             string msg = string.Empty;
114             this.excelHelper.SaveExcelTemplate(columnList, this.FileName, this.SheetName, ref msg);
115         }
116 
117         #endregion
118     }
119 }

5.演示

6.源代码下载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏菩提树下的杨过

msmq发送速度的测试

在一些并发量比较高的"中小型"应用中,如果短期内有大量的数据插入,利用msmq中转是一个不错的选择(petshop就是这么干的),想知道msmq一秒钟内到底能...

2459
来自专栏草根专栏

用VSCode开发一个asp.net core2.0+angular5项目(5): Angular5+asp.net core 2.0 web api文件上传

这部分就讲从angular5的客户端上传图片到asp.net core 2.0的 web api. 这是需要的源码: https://pan.baidu.com...

4115
来自专栏林德熙的博客

WPF 判断USB插拔

首先需要在一个窗口重写OnSourceInitialized,在这里可以拿到窗口的指针

3171
来自专栏Porschev[钟慰]的专栏

前台JS(Jquery)调用后台方法 无刷新级联菜单示例

前台用AJAX直接调用后台方法,老有人发帖提问,没事做个示例 CasMenu.aspx页面: <%@ Page Language="C#" AutoEventW...

3405
来自专栏飞扬的花生

Html5上传插件封装

      前段时间将flash的上传控件替换成使用纯js实现的,在此记录 1.创建标签 <div class="camera-area" style="dis...

3928
来自专栏我和未来有约会

CaseStudy(showcase)数据篇-从XML中获取数据

做silvelight也有一段时间了,相册、游戏,刚刚完成的showcase这个小程序算是一个阶段了。这里就以showcase这个项目来做一下CaseStudy...

1998
来自专栏.NET开发那点事

.NET开源高性能Socket通信中间件Helios介绍及演示

  Helios是一套高性能的Socket通信中间件,使用C#编写。Helios的开发受到Netty的启发,使用非阻塞的事件驱动模型架构来实现高并发高吞吐量。H...

2302
来自专栏木宛城主

两天完成一个小型工程报价系统(三层架构)

花了两天,整理了一下三层架构,顺便练了一个小型三层架构——工程报价系统。 功能很简单,完成基本的增删改查 搭建项目三层结构 ? 界面的设计以及美化 ...

3459
来自专栏hbbliyong

C# ini文件读写类

VC中提供了API函数进行INI文件的读写操作,但是微软推出的C#编程语言中却没有相应的方法,下面是一个C# ini文件读写类, 从网上收集的,很全,就是没有对...

3396
来自专栏菩提树下的杨过

C#执行Javascript代码的几种方法

一、开源项目 Javascript .NET 地址: http://javascriptdotnet.codeplex.com/ 它是Google Chrome...

6525

扫码关注云+社区

领取腾讯云代金券