欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# 文件上传下载(Excel导入,多线程下载)功能的实现代码

程序员文章站 2023-12-09 17:35:09
废话不多说了,直接给大家贴代码,具体代码如下所示: //打开excel文件,转换为datatable       datatable dtexcel;    ...

废话不多说了,直接给大家贴代码,具体代码如下所示:

//打开excel文件,转换为datatable
      datatable dtexcel;
    private void openfile()
    {
      openfiledialog dialog = new openfiledialog();
      dialog.filter = "microsoft excel files(*.xls)|*.xls;*.xlsx"; //筛选打开文件类型 :图片 *.jpg|*.jpg|*.bmp|*.bmp ;"音频文|*.mp3;*.wma;*.aac;*.midi;*.wav" 等等
      if (dialog.showdialog() == dialogresult.ok)
      {
        dialogfilename = dialog.filename;
        dtexcel = exceltodatatable(dialogfilename, "sheet1", true);
      }
    }
/// <summary>
  /// excel转datatable
  /// </summary>
  /// <param name="filename">文件名含后缀名</param>
  /// <param name="sheetname">excel文件,页名称</param>
  /// <param name="isfirstrowcolumn">是否将第一列作为表头</param>
  /// <returns></returns>
  private datatable exceltodatatable(string filename, string sheetname, bool isfirstrowcolumn)
  {
   iworkbook workbook = null;
   filestream fs = null;
   isheet sheet = null;
   datatable data = new datatable();
   int startrow = 0;
   try
   {
    fs = new filestream(filename, filemode.open, fileaccess.read);
    if (filename.indexof(".xlsx") > 0) // 2007版本
     workbook = new xssfworkbook(fs);
    else if (filename.indexof(".xls") > 0) // 2003版本
     workbook = new hssfworkbook(fs);
    if (sheetname != null)
    {
     sheet = workbook.getsheet(sheetname);
     if (sheet == null) //如果没有找到指定的sheetname对应的sheet,则尝试获取第一个sheet
     {
      sheet = workbook.getsheetat(0);
     }
    }
    else
    {
     sheet = workbook.getsheetat(0);
    }
    if (sheet != null)
    {
     irow firstrow = sheet.getrow(0);
     int cellcount = firstrow.lastcellnum; //一行最后一个cell的编号 即总的列数
     if (isfirstrowcolumn)
     {
      for (int i = firstrow.firstcellnum; i < cellcount; ++i)
      {
       icell cell = firstrow.getcell(i);
       if (cell != null)
       {
        string cellvalue = cell.stringcellvalue;
        if (cellvalue != null)
        {
         datacolumn column = new datacolumn(cellvalue);
         data.columns.add(column);
        }
       }
      }
      startrow = sheet.firstrownum + 1;
     }
     else
     {
      startrow = sheet.firstrownum;
     }
     //最后一列的标号
     int rowcount = sheet.lastrownum;
     for (int i = startrow; i <= rowcount; ++i)
     {
      irow row = sheet.getrow(i);
      if (row == null) continue; //没有数据的行默认是null       
      datarow datarow = data.newrow();
      for (int j = row.firstcellnum; j < cellcount; ++j)
      {
       if (row.getcell(j) != null) //同理,没有数据的单元格都默认是null
        datarow[j] = row.getcell(j).tostring();
      }
      data.rows.add(datarow);
     }
    }
    return data;
   }
   catch (exception ex)
   {
    mymessagebox.show(ex.message);
    return null;
   }
  }

文件下载:

private void download()
  {
   if (impdefinebm != null)
   {
    folderbrowserdialog path = new folderbrowserdialog();
    path.showdialog();
    if (path != null && path.selectedpath != "")
    {
     string url = @"http://192.168.1.1/xx.xls";  //下载地址
     string name = "filename";              // 文件名称
     string savefilepath = path.selectedpath + "\\" + name + url.substring(url.lastindexof(".")); //注意:下载文件名的命名 ,可根据实际需求调整调用的文件创建方式
     multidownload download = new multidownload(5, url, savefilepath); //调用多线程下载
     download.start();
    }
   }
  }
 #region 多线程下载
  public class multidownload
  {
   #region 变量
   private int _threadnum;    //线程数量
   private long _filesize;    //文件大小
   private string _fileurl;   //文件地址
   private string _filename;   //文件名
   private string _savepath;   //保存路径
   private short _threadcompletenum; //线程完成数量
   private bool _iscomplete;   //是否完成
   private volatile int _downloadsize; //当前下载大小(实时的)
   private thread[] _thread;   //线程数组
   private list<string> _tempfiles = new list<string>();
   private object locker = new object();
   #endregion
   #region 属性
   /// <summary>
   /// 文件名
   /// </summary>
   public string filename
   {
    get
    {
     return _filename;
    }
    set
    {
     _filename = value;
    }
   }
   /// <summary>
   /// 文件大小
   /// </summary>
   public long filesize
   {
    get
    {
     return _filesize;
    }
   }
   /// <summary>
   /// 当前下载大小(实时的)
   /// </summary>
   public int downloadsize
   {
    get
    {
     return _downloadsize;
    }
   }
   /// <summary>
   /// 是否完成
   /// </summary>
   public bool iscomplete
   {
    get
    {
     return _iscomplete;
    }
   }
   /// <summary>
   /// 线程数量
   /// </summary>
   public int threadnum
   {
    get
    {
     return _threadnum;
    }
   }
   /// <summary>
   /// 保存路径
   /// </summary>
   public string savepath
   {
    get
    {
     return _savepath;
    }
    set
    {
     _savepath = value;
    }
   }
   #endregion
   /// <summary>
   /// 构造函数
   /// </summary>
   /// <param name="threahnum">线程数量</param>
   /// <param name="fileurl">文件url路径</param>
   /// <param name="savepath">本地保存路径</param>
   public multidownload(int threahnum, string fileurl, string savepath)
   {
    this._threadnum = threahnum;
    this._thread = new thread[threahnum];
    this._fileurl = fileurl;
    this._savepath = savepath;
   }
   public void start()
   {
    httpwebrequest request = (httpwebrequest)webrequest.create(_fileurl);
    httpwebresponse response = (httpwebresponse)request.getresponse();
    _filesize = response.contentlength;
    int singelnum = (int)(_filesize / _threadnum);  //平均分配
    int remainder = (int)(_filesize % _threadnum);  //获取剩余的
    request.abort();
    response.close();
    for (int i = 0; i < _threadnum; i++)
    {
     list<int> range = new list<int>();
     range.add(i * singelnum);
     if (remainder != 0 && (_threadnum - 1) == i) //剩余的交给最后一个线程
      range.add(i * singelnum + singelnum + remainder - 1);
     else
      range.add(i * singelnum + singelnum - 1);
     //下载指定位置的数据
     int[] ran = new int[] { range[0], range[1] };
     _thread[i] = new thread(new parameterizedthreadstart(download));
     _thread[i].name = system.io.path.getfilenamewithoutextension(_fileurl) + "_{0}".replace("{0}", convert.tostring(i + 1));
     _thread[i].start(ran);
    }
    //messagebox.show("下载完成!");
   }
   private void download(object obj)
   {
    stream httpfilestream = null, localfilestram = null;
    try
    {
     int[] ran = obj as int[];
     string tmpfileblock = system.io.path.gettemppath() + thread.currentthread.name + ".tmp";
     _tempfiles.add(tmpfileblock);
     httpwebrequest httprequest = (httpwebrequest)webrequest.create(_fileurl);
     httprequest.addrange(ran[0], ran[1]);
     httpwebresponse httpresponse = (httpwebresponse)httprequest.getresponse();
     httpfilestream = httpresponse.getresponsestream();
     localfilestram = new filestream(tmpfileblock, filemode.create);
     byte[] by = new byte[5000];
     int getbytesize = httpfilestream.read(by, 0, (int)by.length); //read方法将返回读入by变量中的总字节数
     while (getbytesize > 0)
     {
      thread.sleep(20);
      lock (locker) _downloadsize += getbytesize;
      localfilestram.write(by, 0, getbytesize);
      getbytesize = httpfilestream.read(by, 0, (int)by.length);
     }
     lock (locker) _threadcompletenum++;
    }
    catch (exception ex)
    {
     throw new exception(ex.message.tostring());
    }
    finally
    {
     if (httpfilestream != null) httpfilestream.dispose();
     if (localfilestram != null) localfilestram.dispose();
    }
    if (_threadcompletenum == _threadnum)
    {
     complete();
     _iscomplete = true;
    }
   }
   /// <summary>
   /// 下载完成后合并文件块
   /// </summary>
   private void complete()
   {
    stream mergefile = null;
    binarywriter addwriter = null;
    try
    {
     using (mergefile = new filestream(@_savepath, filemode.create)) //根据实际情况调整filemode
     {
      addwriter = new binarywriter(mergefile);
      foreach (string file in _tempfiles)
      {
       using (filestream fs = new filestream(file, filemode.open))
       {
        binaryreader tempreader = new binaryreader(fs);
        addwriter.write(tempreader.readbytes((int)fs.length));
        tempreader.close();
       }
       file.delete(file);
      }
     }
     mymessagebox.show("下载完成!");
    }
    catch (exception ex)
    {
     throw new exception(ex.message);
    }
    finally
    {
     if (addwriter != null)
     {
      addwriter.close();
      addwriter.dispose();
     }
     if (mergefile != null)
     {
      mergefile.close();
      mergefile.dispose();
     }
    }
   }
  }

总结

以上所述是小编给大家介绍的c# 文件上传下载(excel导入,多线程下载)功能的实现代码,希望对大家有所帮助