• OpenXML_导入Excel到数据库(转)


    (1).实现功能:通过前台选择.xlsx文件的Excel,将其文件转化为DataTable和List集合

    (2).开发环境:Window7旗舰版+vs2013+Mvc4.0

    (2).在使用中需要用到的包和dll

      1.用NuGet引入OpenXML包【全名叫DocumentFormat.OpenXml】=》注意:现在导入的Excel只支持.xlsx结尾的Excel,若导入.xls结尾的则会出现【文件包含损坏的数据】的错误!

      2.WindowsBase.dll

    (3).MVC中通过file选择文件并用submit提交到Controller方法如下:

        3.1:前台代码

    <form action="Home/FileUpload" method="post" enctype="multipart/form-data">
        <div style="100%;height:auto;
            <input id="uploadfile" type="file" name="file" />
            <input type="submit" value="上传Excel" />
        </div>
    </form>

        3.2:Controller代码

    /// <summary>
    /// form提交回的Action
    /// </summary>
    /// <returns></returns>
    public ActionResult FileUpload()
    {
        //1.假设选择一个Excel文件  获取第一个Excel文件
        var stream = Request.Files[0].InputStream;
        //2.将选择的文件转换为DataTable
        var rst = new StreamToDataTable().ReadExcel(stream);
        //3.将DataTable转换为List集合
        var list = this.TableToLists(rst);
        return View();
    }
    /// <summary>
    /// 加载Excel数据
    /// </summary>
    public List<ExcelImport> TableToLists(System.Data.DataTable table)
    {
        TBToList<ExcelImport> tables = new TBToList<ExcelImport>();
        var lists = tables.ToList(table);
        return lists;
    }

    (4).Excel流组织成Datatable方法实现

    public class StreamToDataTable
       {
           /// <summary>
           /// Excel流组织成Datatable
           /// </summary>
           /// <param name="stream">Excel文件流</param>
           /// <returns>DataTable</returns>
           public DataTable ReadExcel(Stream stream)
           {
               using (SpreadsheetDocument document = SpreadsheetDocument.Open(stream, false))     //若导入.xls格式的Excel则会出现【文件包含损坏的数据】的错误!
               {
                   //打开Stream
                   IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>();
                   if (sheets.Count() == 0)
                   {//找出符合条件的sheet,没有则返回
                       return null;
                   }
     
                   WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);
                   //获取Excel中共享数据
                   SharedStringTable stringTable = document.WorkbookPart.SharedStringTablePart.SharedStringTable;
                   IEnumerable<Row> rows = worksheetPart.Worksheet.Descendants<Row>();//得到Excel中得数据行
     
                   DataTable dt = new DataTable("Excel");
                   //因为需要将数据导入到DataTable中,所以我们假定Excel的第一行是列名,从第二行开始是行数据
                   foreach (Row row in rows)
                   {
                       if (row.RowIndex == 1)
                       {
                           //Excel第一行为列名
                           GetDataColumn(row, stringTable, ref dt);
                       }
                       GetDataRow(row, stringTable, ref dt);//Excel第二行同时为DataTable的第一行数据
                   }
                   return dt;
               }
           }
     
     
           /// <summary>
           /// 根据给定的Excel流组织成Datatable
           /// </summary>
           /// <param name="stream">Excel文件流</param>
           /// <param name="sheetName">需要读取的Sheet</param>
           /// <returns>组织好的DataTable</returns>
           public DataTable ReadExcelBySheetName(string sheetName, Stream stream)
           {
               using (SpreadsheetDocument document = SpreadsheetDocument.Open(stream, false))
               {//打开Stream
                   IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName);
                   if (sheets.Count() == 0)
                   {//找出符合条件的sheet,没有则返回
                       return null;
                   }
     
                   WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);
     
                   //获取Excel中共享数据
                   SharedStringTable stringTable = document.WorkbookPart.SharedStringTablePart.SharedStringTable;
                   IEnumerable<Row> rows = worksheetPart.Worksheet.Descendants<Row>();//得到Excel中得数据行
     
                   DataTable dt = new DataTable("Excel");
                   //因为需要将数据导入到DataTable中,所以我们假定Excel的第一行是列名,从第二行开始是行数据
                   foreach (Row row in rows)
                   {
                       if (row.RowIndex == 1)
                       {
                           //Excel第一行为列名
                           GetDataColumn(row, stringTable, ref dt);
                       }
                       GetDataRow(row, stringTable, ref dt);//Excel第二行同时为DataTable的第一行数据
                   }
                   return dt;
               }
           }
     
           /// <summary>
           /// 构建DataTable的列
           /// </summary>
           /// <param name="row">OpenXML定义的Row对象</param>
           /// <param name="stringTablePart"></param>
           /// <param name="dt">需要返回的DataTable对象</param>
           /// <returns></returns>
           public void GetDataColumn(Row row, SharedStringTable stringTable, ref DataTable dt)
           {
               DataColumn col = new DataColumn();
               foreach (Cell cell in row)
               {
                   string cellVal = GetValue(cell, stringTable);
                   col = new DataColumn(cellVal);
                   dt.Columns.Add(col);
               }
           }
     
           /// <summary>
           /// 构建DataTable的每一行数据,并返回该Datatable
           /// </summary>
           /// <param name="row">OpenXML的行</param>
           /// <param name="stringTablePart"></param>
           /// <param name="dt">DataTable</param>
           private void GetDataRow(Row row, SharedStringTable stringTable, ref DataTable dt)
           {
               // 读取算法:按行逐一读取单元格,如果整行均是空数据
               // 则忽略改行(因为本人的工作内容不需要空行)-_-
               DataRow dr = dt.NewRow();
               int i = 0;
               int nullRowCount = i;
               foreach (Cell cell in row)
               {
                   string cellVal = GetValue(cell, stringTable);
                   if (cellVal == string.Empty)
                   {
                       nullRowCount++;
                   }
                   dr[i] = cellVal;
                   i++;
               }
               if (nullRowCount != i)
               {
                   dt.Rows.Add(dr);
               }
           }
     
     
           /// <summary>
           /// 获取单元格的值
           /// </summary>
           /// <param name="cell"></param>
           /// <param name="stringTablePart"></param>
           /// <returns></returns>
           private string GetValue(Cell cell, SharedStringTable stringTable)
           {
               //由于Excel的数据存储在SharedStringTable中,需要获取数据在SharedStringTable 中的索引
               string value = string.Empty;
               try
               {
                   if (cell.ChildElements.Count == 0)
                       return value;
     
                   value = double.Parse(cell.CellValue.InnerText).ToString();
     
                   if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString))
                   {
                       value = stringTable.ChildElements[Int32.Parse(value)].InnerText;
                   }
               }
               catch (Exception)
               {
                   value = "N/A";
               }
               return value;
           }
     
       }

    (5).Datatable组织为List方法实现

    转自:http://www.cnblogs.com/pfwbloghome/p/4969792.html

  • 相关阅读:
    [MSSQL]也说SQL中显示星期几函数
    ECMAScript旮里旮旯儿一(galigalaoer)
    [MSQL]RANK函数
    敏捷背后的理论
    敏捷软件开发 Agile software Development
    第三章 WebGL资源 WebGL Resources
    第一章 WebGL简介 Introduction
    [MSSQL]PIVOT函数
    《Javascript高级程序设计》读书笔记 Number对象
    visual studio 2010 冷门技巧分享
  • 原文地址:https://www.cnblogs.com/nele/p/4970085.html
Copyright © 2020-2023  润新知