zoukankan      html  css  js  c++  java
  • Winform:SaveFileDialog使用(数据导出示例)

    在做邮件群发器时,会将未发送列表中的邮件地址进行Excel导出保存,在日后群发时导入继续发送的功能。

    该邮件群发器是以xml作为存储介质,开始的思路是想把xml数据以流的形式输出在内存中,提供客户下载。可是不知道怎么操作。去问同事,同事告诉我生成一个静态文本,让其下载时直接下载该文本就行,答非所问。无奈之下之后继续Google,中文搜索关键字不靠谱,被迫只能使用英文关键字(winform SaveFileDialog),还是老外从来都不会让我失望。

    从中找到一篇标题为《Win Form: SaveFileDialog》的文章,该文章解决了困扰我一早上的问题。对于其中的代码进行修改,已经达到我所需要的目的.

    在使用中发现StreamWriter中文乱码的问题,解决方案详情请参照StreamWriter 构造函数

    下边贴出具体实现代码:

    private void ToExcel()
            {
                SaveFileDialog dlg = new SaveFileDialog();
    
                /****************
                 * 这里需要说明下"所有文件(*.*)|*.*"配置是成对出现的,不然程序运行时会报如下错误:
                 * "提供的筛选器字符串无效。筛选器字符串必须包含筛选器的说明,后跟竖线(|)和筛选模式。不同筛选选项的字符串还必须以竖线分隔。例如:“文本文件(*.txt)|*.txt|所有文件(*.*)|*.*”"
                ****************/
                dlg.Filter = "所有文件(*.*)|*.*|Excel2003(*.xls)|*.xls|Excel2003以上版本(*.xlsx)|*.xlsx";
                dlg.Title = "导出Excel文件";
                dlg.FilterIndex = 2;//索引从1开始
    
                //是否检查文件是否存在
                dlg.CheckPathExists = true;
    
                if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK && dlg.FileName.Length > 0)
                {
                    StreamWriter streamWriter = new StreamWriter(dlg.FileName, false, Encoding.GetEncoding("GB2312"));
                    //"\t"代表换一列
                    streamWriter.Write("收件人\t企业名称");
                    //注意:streamWriter.NewLine等价于"\r\n"代表换行的意思
                    streamWriter.Write(streamWriter.NewLine);
                    //streamWriter.Write("\r\n");
                    streamWriter.Write("address@mail.com\r\n");
                    streamWriter.Write("address@mail.com\r\n");
                    streamWriter.Write("address@mail.com\r\n");
                    streamWriter.Close();
                }
            }

    在实际的应用中,上述方法只适合生成文本文件(txt)。此处生成的Excel实际上并不是真正意义上的Excel文件,只是把txt后缀名改成xls的文本文件而已,因此对其进行读取等操作是非常麻烦的。但是要直接生成真正意义上的Excel很麻烦,至今未找到好的解决方案。只晓得Dev组件里封装好的功能是不需要任何模板,就可以动态生成Excel的。具体机制没有源码不得而知。大家一般常用的方法就是读取一个现成的模板然后对其进行CRUD的操作,然后让客户保存。这种方法是我最不喜欢使用的,可是为赶项目又不得不去使用。毕竟在工作中用户看的是你能不能在规定的时间内做出他要东西,而不是耗费到他不能接受的时间给他一个你自认为是好的产品。反正用户只是要一个下载功能而已。程序如何好如何差的执行,跟他们没有半毛钱的关系。这不是他们所关注的。

    下边贴出通过模板具体实现的导入导出Excel的代码,具体实现原理就是通过OleDbConnection类来实现,可以简单的理解为是操作数据库。不过Excel的第一行类似于数据库中的列名罢了。操作过数据库的人对于下列代码不会感到陌生。

    导出Demo:

    SaveFileDialog dlg = new SaveFileDialog();
    
    dlg.Filter = "所有文件(*.*)|*.*|Excel2003(*.xls)|*.xls|Excel2003以上版本(*.xlsx)|*.xlsx";
    dlg.Title = "导出Excel文件";
    dlg.FilterIndex = 2;//索引从1开始
    dlg.FileName = "SaveMailAddress.xls";
    
    //是否检查文件是否存在
    dlg.CheckPathExists = true;
    
    if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK && dlg.FileName.Length > 0)
    {
         #region 读取Excel模板 给其添加行数据 核心代码
          //模板路径
          string filePathTemplate = workDir + "data" + Path.DirectorySeparatorChar + "ImportExportTemplate.xls";
         //记得要拷贝模板文件,否则CRUD操作会直接针对原模板进行操作
          File.Copy(filePathTemplate, dlg.FileName, true);
         //连接Excel字符串
          string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dlg.FileName + ";Extended Properties='Excel 8.0;'";
         //如下代码跟操作数据库是一个概念
          using (OleDbConnection conn = new OleDbConnection(strConn))
         {
              conn.Open();
              OleDbCommand Cmd = new OleDbCommand("", conn);
              foreach (string add in listMailAddress.Items)
              {
                    //执行SQL语句
                       Cmd.CommandText = "insert into [Sheet1$] ([收件人],[企业名称]) values ('" + add + "','')";
                    Cmd.ExecuteNonQuery();
              }
              //使用using如下关闭代码可以省略
                //conn.Close();
         }
    #endregion

    导入Demo:

    OpenFileDialog dlg = new OpenFileDialog();
    dlg.Filter = "Excel 2003(*.xls)|*.xls|Excel 2003以上版本(*.xlsx)|*.xlsx|所有文件(*.*)|*.*";
    dlg.Title = "导入Excel文件";
    if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK && dlg.FileName.Length > 0)
    {
         //获取全部数据
          using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dlg.FileName + ";Extended Properties='Excel 8.0;'"))
         {
              conn.Open();
              OleDbCommand cmd = new OleDbCommand("select * from [Sheet1$]", conn);
              OleDbDataReader r = cmd.ExecuteReader();
              listMailAddress.Items.Clear();
              while (r.Read())
              {
                    listMailAddress.Items.Add(r[0].ToString());//索引代表列
                }
              //conn.Close();
          }
    }

    Excel格式为:

    注意的是"收件人","企业名称"均为列名,并且要放在Excel的第一行

      A B C D E F G
    1 收件人 企业名称          
    2              
    3              

    电脑维修网

  • 相关阅读:
    uboot 环境变量
    U-boot的环境变量: bootcmd 和bootargs
    linux中的rootfs/initrd/ramfs/initramfs
    关于Linux启动时挂载rootfs的几种方式
    u-boot-2011.06在基于s3c2440开发板的移植之引导内核与加载根文件系统
    MySQL列出当前月的每一天
    SQL 标量函数-----日期函数 day() 、month()、year()
    mysql 中 DATE_ADD函数和 DATE_SUB函数用法
    mysql 中 DATE_ADD(date,INTERVAL expr type)
    mysql中date_add()函数的使用?
  • 原文地址:https://www.cnblogs.com/frlmoney/p/3025877.html
Copyright © 2011-2022 走看看