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

作者:大白菜1990 时间:2021-12-09 20:16:34 

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


//打开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导入,多线程下载)功能的实现代码网站的支持!

来源:http://www.cnblogs.com/liudiwei/p/6041641.html

标签:c#,上传,下载,多线程下载
0
投稿

猜你喜欢

  • Java JDK动态代理实现原理实例解析

    2022-04-23 05:19:10
  • 详解springmvc常用5种注解

    2023-03-27 15:15:43
  • springboot调用支付宝第三方接口(沙箱环境)

    2023-11-25 06:12:08
  • java中驼峰与下划线的写法互转

    2023-09-21 09:47:36
  • 详解Eclipse 字体、字号的设置、最佳字体推荐

    2023-11-26 12:25:32
  • Java 线程池ExecutorService详解及实例代码

    2022-09-02 17:07:24
  • 使用java + selenium + OpenCV破解腾讯防水墙滑动验证码功能

    2023-07-23 14:32:47
  • Maven的生命周期与自定义插件实现方法

    2022-04-06 20:13:48
  • springcloud eureka切换nacos的配置方法

    2022-05-19 01:58:47
  • Java实现文本编译器

    2022-10-21 18:33:20
  • 解析C#多线程编程中异步多线程的实现及线程池的使用

    2021-10-23 02:36:23
  • Java递归运行的机制:递归的微观解读图文分析

    2022-09-24 20:04:09
  • java中超过long范围的超大整数相加算法详解(面试高频)

    2022-09-15 11:22:05
  • 将JavaDoc注释生成API文档的操作

    2023-06-16 18:24:06
  • IntelliJ IDEA中properties文件显示乱码问题的解决办法

    2021-09-08 04:59:03
  • spring是如何解析xml配置文件中的占位符

    2023-12-02 05:57:12
  • springboottest测试依赖和使用方式

    2021-11-21 13:41:38
  • 详解Vue响应式的部分实现

    2022-12-21 23:25:53
  • Spring Boot详解创建和运行基础流程

    2022-01-28 19:57:05
  • Java SSM框架如何配置静态资源加载

    2023-03-22 17:40:01
  • asp之家 软件编程 m.aspxhome.com