C# 文件上传下载(Excel导入,多线程下载)功能的实现代码
程序员文章站
2023-12-16 13:36:46
废话不多说了,直接给大家贴代码,具体代码如下所示:
//打开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导入,多线程下载)功能的实现代码,希望对大家有所帮助