• .NET导入导出Excel方法总结


    最近,应项目的需求,需要实现Excel的导入导出功能,对于Web架构的Excel导入导出功能,比较传统的实现方式是:

    1)导入Excel:将Excel文件上传到服务器的某一文件夹下,然后在服务端完成Excel的读取及数据的存储;

    2)导出Excel:在服务端生成需要导出的Excel,然后下载到客户端。

    其中,文件的上传和下载本文不在详述,以下主要写一些DataTable或DataSet与Excel之间的相互转换。

    转换方式多种多样,网上也有很多前辈分享的代码实现,本文也借鉴了前辈的诸多思路及代码,具体方法如下:

    1. DCOM方式

    使用DCOM方式实现Excel的导入导出功能,首先需要在服务端安装office软件。

    具体实现代码如下:

    1)数据导出到Excel

        public class ExportExcel : IDisposable
        {
            private Excel.ApplicationClass excelApp;
            private Excel.Workbook workBook;
            private Excel.Worksheet workSheet;
            private Excel.Range range;
    
            public void DataTableToExcel(DataTable sourceTable, string fileName)
            {
                excelApp = new Excel.ApplicationClass();
                if (excelApp == null)
                {
                    throw new Exception("打开Excel程序错误!");
                }
    
                workBook = excelApp.Workbooks.Add(true);
                workSheet = (Excel.Worksheet)workBook.Worksheets[1];
                int rowIndex = 0;          
    
                //写入列名
                ++rowIndex;
                for (int i = 0; i < sourceTable.Columns.Count; i++)
                {
                    workSheet.Cells[rowIndex, i + 1] = sourceTable.Columns[i].ColumnName;
                }
                range = workSheet.get_Range(workSheet.Cells[rowIndex, 1], workSheet.Cells[rowIndex, sourceTable.Columns.Count]);
    
                FontStyle headerStyle = new FontStyle
                {
                    FontSize = 30,
                    BordersValue = 1,
                    FontBold = true,
                    EntireColumnAutoFit = true
                };
                FontStyleHelper.SetFontStyleForRange(range, headerStyle);
    
                //写入数据
                ++rowIndex;
                for (int r = 0; r < sourceTable.Rows.Count; r++)
                {
                    for (int i = 0; i < sourceTable.Columns.Count; i++)
                    {
                        workSheet.Cells[rowIndex, i + 1] = ExportHelper.ConvertToCellData(sourceTable, r, i);
                    }
                    rowIndex++;
                }
                range = workSheet.get_Range(workSheet.Cells[2, 1], workSheet.Cells[sourceTable.Rows.Count + 1, sourceTable.Columns.Count]);
                FontStyle bodyStyle = new FontStyle
                {
                    FontSize = 16,
                    BordersValue = 1,
                    FontAlign = Infrastruction.FontAlign.Right,
                    EntireColumnAutoFit = true
                };
                FontStyleHelper.SetFontStyleForRange(range, bodyStyle);
    
                //只保存一个sheet页
                //workSheet.SaveAs(fileName, Excel.XlFileFormat.xlTemplate, Type.Missing, Type.Missing, Type.Missing,
                //        Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing);
                //保存整个Excel
                workBook.SaveAs(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                        Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing);
                workBook.Close(false, Type.Missing, Type.Missing);
                excelApp.Quit();
    
                Dispose();
            }
    
            public void Dispose()
            {
                GC.Collect();
                BaseExcel.Dispose(excelApp, workSheet, workBook, range);
            }
        }
    View Code

    2)数据导入到内存

        public class ImportExcel : IDisposable
        {
            private Excel.ApplicationClass excelApp;
            private Excel.Workbook workBook;
            private Excel.Worksheet workSheet;
            private Excel.Range range;
    
            public DataSet ExcelToDataSet(string fileName)
            {
                if (!File.Exists(fileName))
                {
                    return null;
                }
                FileInfo file = new FileInfo(fileName);
                string strConnection = string.Empty;
                string extension = file.Extension;
                string vsSql = string.Empty;
                switch (extension)
                {
                    case ".xls":
                        strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1;'";
                        break;
                    case ".xlsx":
                        strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=1;'";
                        break;
                    default:
                        strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=1;'";
                        break;
                }
                DataSet ds = ImportHelper.GetDataSetFromExcel(strConnection);
    
                Dispose();
                ds = ImportHelper.ConvertDataSet(ds);
                return ds;
            }
    
            public DataSet ExcelToDataSetByDcom(string fileName)
            {
                DataSet result = null;
                excelApp = new Excel.ApplicationClass();
                if (excelApp == null)
                {
                    throw new Exception("打开Excel程序错误!");
                }
    
                excelApp.Visible = false; excelApp.UserControl = true;
                // 以只读的形式打开EXCEL文件
                workBook = excelApp.Application.Workbooks.Open(fileName, Type.Missing, true, Type.Missing, Type.Missing, Type.Missing,
                 Type.Missing, Type.Missing, Type.Missing, true, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
    
                int sheets = workBook.Worksheets.Count;
                if (sheets >= 1)
                {
                    result = new DataSet();
                }
                for(int i = 1; i <= sheets; i++)
                {
                    workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i);
                    string sheetName = workSheet.Name;
    
                    DataTable dt = new DataTable();
                    dt.TableName = sheetName;
    
                    //取得总记录行数
                    int rows = workSheet.UsedRange.Cells.Rows.Count; //得到行数
                    int columns = workSheet.UsedRange.Cells.Columns.Count;//得到列数
                    if (rows == 0 || columns == 0) return null;
                    //取得数据范围区域
                    range = workSheet.get_Range(workSheet.Cells[1, 1], workSheet.Cells[rows, columns]);
                    object[,] arryItem = (object[,])range.Value2; //get range's value
    
                    //生成DataTable的列
                    for(int col = 1; col <= columns; col++)
                    {
                        string dcName = arryItem[1, col].ToString().Trim();
                        DataColumn dc = new DataColumn(dcName, typeof(string));
                        dt.Columns.Add(dc);
                    }
                    //将数据填充到DataTable
                    for(int row = 2; row <= rows; row++)
                    {
                        object[] rowvalue = new object[columns];
                        for (int col = 1; col <= columns; col++)
                        {
                            rowvalue[col - 1] = arryItem[row, col];
                        }
                        dt.Rows.Add(rowvalue);
                    }
                    //将DataTable填充到DataSet
                    result.Tables.Add(dt);
                }
    
                //清理非托管对象
                workBook.Close(false, Type.Missing, Type.Missing);
                excelApp.Quit();
                Dispose();
                return result;
            }
    
            public void Dispose()
            {
                GC.Collect();
                BaseExcel.Dispose(excelApp, workSheet, workBook, range);
            }
        }
    View Code

    3)其他辅助类

        public class BaseExcel
        {
            /// <summary>
            /// 释放Excel资源
            /// </summary>
            /// <param name="excelApp"></param>
            public static void Dispose(Excel.ApplicationClass excelApp, Excel.Worksheet workSheet, Excel.Workbook workBook, Excel.Range range)
            {
                //清理非托管的代码
                if (workSheet != null)
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(workSheet);
                    workSheet = null;
                }
                if (workBook != null)
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(workBook);
                    workBook = null;
                }
                if (excelApp != null)
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
                    excelApp = null;
                }
                if (range != null)
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                    range = null;
                }
                KillProcess();
            }
            /// <summary>
            /// 关闭进程
            /// </summary>
            /// <param name="hwnd"></param>
            /// <param name="ID"></param>
            /// <returns></returns>
            [DllImport("User32.dll", CharSet = CharSet.Auto)]
            public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
            private static void Kill(Excel.Application excel)
            {
                int id = 0;
                IntPtr intptr = new IntPtr(excel.Hwnd);    //得到这个句柄,具体作用是得到这块内存入口
                System.Diagnostics.Process p = null;
                try
                {
                    GetWindowThreadProcessId(intptr, out id);  //得到本进程唯一标志
                    p = System.Diagnostics.Process.GetProcessById(id);  //得到对进程k的引用
                    if (p != null)
                    {
                        p.Kill();  //关闭进程k
                        p.Dispose();
                    }
                }
                catch
                {
                }
            }
            //强制结束进程
            private static void KillProcess()
            {
                System.Diagnostics.Process[] allProcess = System.Diagnostics.Process.GetProcesses();
                foreach (System.Diagnostics.Process thisprocess in allProcess)
                {
                    string processName = thisprocess.ProcessName;
                    if (processName.ToLower() == "excel")
                    {
                        try
                        {
                            thisprocess.Kill();
                        }
                        catch
                        {
                        }
                    }
                }
            }
        }
    BaseExcel
        public class FontStyle
        {
            /// <summary>
            /// 字体大小
            /// </summary>
            public int FontSize { get; set; }
            /// <summary>
            /// 字体名称
            /// </summary>
            public string FontName { get; set; }
            /// <summary>
            /// 是否为粗体
            /// </summary>
            public bool FontBold { get; set; }
            /// <summary>
            /// 字体对齐方式
            /// </summary>
            public FontAlign FontAlign { get; set; }
            /// <summary>
            /// 边框样式
            /// </summary>
            public int BordersValue { get; set; }
            /// <summary>
            /// 字体颜色索引
            /// </summary>
            public int FontColorIndex { get; set; }
            /// <summary>
            /// 背景颜色索引
            /// </summary>
            public int InteriorColorIndex { get; set; }
            /// <summary>
            /// 列宽自适应
            /// </summary>
            public bool EntireColumnAutoFit { get; set; }
        }
    
        public enum FontAlign
        {
            Center,
            Right,
            Left
        }
    FontStyle
        public class FontStyleHelper
        {
            /// <summary>
            /// 对选中区域设置格式
            /// </summary>
            /// <param name="range">选中区域</param>
            /// <param name="fontStyle">样式表</param>
            public static void SetFontStyleForRange(Excel.Range range, FontStyle fontStyle)
            {
                if (fontStyle.FontSize != 0)
                {
                    range.Font.Size = fontStyle.FontSize;
                }
                if (fontStyle.FontName != null)
                {
                    range.Font.Name = fontStyle.FontName;
                }
                if (fontStyle.FontBold != false)
                {
                    range.Font.Bold = fontStyle.FontBold;
                }
                if (fontStyle.FontAlign == FontAlign.Center)
                {
                    range.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                }
                else if (fontStyle.FontAlign == FontAlign.Left)
                {
                    range.HorizontalAlignment = Excel.XlHAlign.xlHAlignLeft;
                }
                else if (fontStyle.FontAlign == FontAlign.Right)
                {
                    range.HorizontalAlignment = Excel.XlHAlign.xlHAlignRight;
                }
                if (fontStyle.BordersValue != 0)
                {
                    range.Borders.Value = fontStyle.BordersValue;
                }
                if (fontStyle.FontColorIndex != 0)
                {
                    range.Font.ColorIndex = fontStyle.FontColorIndex;
                }
                if (fontStyle.InteriorColorIndex != 0)
                {
                    range.Interior.ColorIndex = fontStyle.InteriorColorIndex;
                }
                if (fontStyle.EntireColumnAutoFit == true)
                {
                    range.EntireColumn.AutoFit();
                }
            }
        }
    FontStyleHelper
        public class ExportHelper
        {
            public static string ConvertToCellData(DataTable sourceTable, int rowIndex, int colIndex)
            {
                DataColumn col = sourceTable.Columns[colIndex];
                object data = sourceTable.Rows[rowIndex][colIndex];
                if (col.DataType == System.Type.GetType("System.DateTime"))
                {
                    if (data.ToString().Trim() != "")
                    {
                        return Convert.ToDateTime(data).ToString("yyyy-MM-dd HH:mm:ss");
                    }
                    else
                    {
                        return (Convert.ToDateTime(DateTime.Now)).ToString("yyyy-MM-dd HH:mm:ss");
                    }
                }
                else if (col.DataType == System.Type.GetType("System.String"))
                {
                    return "'" + data.ToString().Trim();
                }
                else
                {
                    return data.ToString().Trim();
                }
            }
        }
    ExportHelper
        public class ImportHelper
        {
            /// <summary>
            /// 通过OleDb获得DataSet
            /// </summary>
            /// <param name="connStr"></param>
            /// <param name="sheetNames"></param>
            /// <returns></returns>
            public static DataSet GetDataSetFromExcel(string connStr)
            {
                DataSet ds = null;
                using (OleDbConnection conn = new OleDbConnection(connStr))
                {
                    try
                    {
                        conn.Open();
                        DataTable tblName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
                        if (tblName.Rows.Count < 1 || tblName == null)
                        {
                            conn.Close();
                            return null;
                        }
                        else
                        {
                            ds = new DataSet();
                            DataTable tbl = null;
                            for (int i = 0; i < tblName.Rows.Count; i++)
                            {
                                tbl = new DataTable();
                                tbl.TableName = tblName.Rows[i]["TABLE_NAME"].ToString().Replace("$", "");
                                string vsSql = "SELECT * FROM [" + tblName.Rows[i]["TABLE_NAME"].ToString() + "]";
                                OleDbDataAdapter myCommand = new OleDbDataAdapter(vsSql, conn);
                                myCommand.Fill(tbl);
                                ds.Tables.Add(tbl.Copy());
                                tbl.Dispose();
                                tbl = null;
                            }
                            conn.Close();
                        }
                    }
                    catch (Exception ex)
                    {
                        conn.Close();
                        throw new Exception(ex.Source + ":" + ex.Message);
                    }
                }
                return ds;
            }
    
            public static DataSet ConvertDataSet(DataSet source)
            {
                if (source == null) return null;
    
                DataSet result = new DataSet();
                int dataTableCount = source.Tables.Count;
                DataTable temp = null;
                for (int i = 0; i < dataTableCount; i++)
                {
                    temp = ConvertDataTable(source.Tables[i]);
                    result.Tables.Add(temp);
                    result.Tables[i].TableName = source.Tables[i].TableName;
                }
                return result;
            }
    
            private static DataTable ConvertDataTable(DataTable source)
            {
                DataTable result = new DataTable();
                int columnsCount = source.Columns.Count;
                int rowsCount = source.Rows.Count;
                for (int i = 0; i < columnsCount; i++)
                {
                    DataColumn column = new DataColumn(source.Rows[0][i].ToString().Trim());
                    result.Columns.Add(column);
                }
                DataRow dr;
                for (int r = 1; r < rowsCount; r++)
                {
                    dr = result.NewRow();
                    for (int c = 0; c < columnsCount; c++)
                    {
                        dr[c] = source.Rows[r][c].ToString().Trim();
                    }
                    result.Rows.Add(dr);
                }
                return result;
            }
        }
    ImportHelper

    2. Open XML方式

      该方法只针对office2007及以上版本有效,因为office2007以上版本是基于XML实现的数据存储,详细内容不做讲解,有兴趣的网友可以将Excel文件扩展名修改为zip并解压,然后对解压出的文件进行分析。

     以Open XML的方式实现Excel的导入导出,需要先下载并安装Open XML Format SDK 2.0及其以上版本,具体下载地址为:https://www.microsoft.com/en-us/download/details.aspx?id=5124。SDK默认会安装在C:Program Files (x86)Open XML Format SDKV2.0 (64bit)目录下,lib子目录下的DocumentFormat.OpenXml.dll必须被引用到项目中。

    具体代码如下:

        public class ExcelOperater
        {
            #region 读取Excel
            /// <summary>
            /// 将Excel数据读取到DataSet
            /// </summary>
            /// <param name="filePath"></param>
            /// <returns></returns>
            public DataSet ExcelToDataSet(string filePath)
            {
                DataSet dataSet = new DataSet();
                try
                {
                    using (SpreadsheetDocument spreadDocument = SpreadsheetDocument.Open(filePath, false))
                    {
                        //指定WorkbookPart对象
                        WorkbookPart workBookPart = spreadDocument.WorkbookPart;
                        //获取Excel中SheetName集合
                        List<string> sheetNames = GetSheetNames(workBookPart);
    
                        foreach (string sheetName in sheetNames)
                        {
                            DataTable dataTable = WorkSheetToTable(workBookPart, sheetName);
                            if (dataTable != null)
                            {
                                dataSet.Tables.Add(dataTable);//将表添加到数据集
                            }
                        }
                    }
                }
                catch (Exception exp)
                {
                    //throw new Exception("可能Excel正在打开中,请关闭重新操作!");
                }
                return dataSet;
            }
    
            /// <summary>
            /// 将Excel数据读取到DataTable
            /// </summary>
            /// <param name="sheetName"></param>
            /// <param name="filePath"></param>
            /// <returns></returns>
            public DataTable ExcelToDataTable(string sheetName, string filePath)
            {
                DataTable dataTable = new DataTable();
                try
                {
                    //根据Excel流转换为spreadDocument对象
                    using (SpreadsheetDocument spreadDocument = SpreadsheetDocument.Open(filePath, false))//Excel文档包
                    {
                        //Workbook workBook = spreadDocument.WorkbookPart.Workbook;//主文档部件的根元素
                        //Sheets sheeets = workBook.Sheets;//块级结构(如工作表、文件版本等)的容器
                        WorkbookPart workBookPart = spreadDocument.WorkbookPart;
                        //获取Excel中SheetName集合
                        List<string> sheetNames = GetSheetNames(workBookPart);
    
                        if (sheetNames.Contains(sheetName))
                        {
                            //根据WorkSheet转化为Table
                            dataTable = WorkSheetToTable(workBookPart, sheetName);
                        }
                    }
                }
                catch (Exception exp)
                {
                    //throw new Exception("可能Excel正在打开中,请关闭重新操作!");
                }
                return dataTable;
            }
    
            /// <summary>
            /// 获取Excel中的sheet页名称
            /// </summary>
            /// <param name="workBookPart"></param>
            /// <returns></returns>
            private List<string> GetSheetNames(WorkbookPart workBookPart)
            {
                List<string> sheetNames = new List<string>();
                Sheets sheets = workBookPart.Workbook.Sheets;
                foreach (Sheet sheet in sheets)
                {
                    string sheetName = sheet.Name;
                    if (!string.IsNullOrEmpty(sheetName))
                    {
                        sheetNames.Add(sheetName);
                    }
                }
                return sheetNames;
            }
    
            /// <summary>
            /// 获取指定sheet名称的Excel数据行集合
            /// </summary>
            /// <param name="workBookPart"></param>
            /// <param name="sheetName"></param>
            /// <returns></returns>
            public IEnumerable<Row> GetWorkBookPartRows(WorkbookPart workBookPart, string sheetName)
            {
                IEnumerable<Row> sheetRows = null;
                //根据表名在WorkbookPart中获取Sheet集合
                IEnumerable<Sheet> sheets = workBookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName);
                if (sheets.Count() == 0)
                {
                    return null;//没有数据
                }
    
                WorksheetPart workSheetPart = workBookPart.GetPartById(sheets.First().Id) as WorksheetPart;
                //获取Excel中得到的行
                sheetRows = workSheetPart.Worksheet.Descendants<Row>();
    
                return sheetRows;
            }
    
            /// <summary>
            /// 将指定sheet名称的数据转换成DataTable
            /// </summary>
            /// <param name="workBookPart"></param>
            /// <param name="sheetName"></param>
            /// <returns></returns>
            private DataTable WorkSheetToTable(WorkbookPart workBookPart, string sheetName)
            {
                //创建Table
                DataTable dataTable = new DataTable(sheetName);
    
                //根据WorkbookPart和sheetName获取该Sheet下所有行数据
                IEnumerable<Row> sheetRows = GetWorkBookPartRows(workBookPart, sheetName);
                if (sheetRows == null || sheetRows.Count() <= 0)
                {
                    return null;
                }
    
                //将数据导入DataTable,假定第一行为列名,第二行以后为数据
                foreach (Row row in sheetRows)
                {
                    //获取Excel中的列头
                    if (row.RowIndex == 1)
                    {
                        List<DataColumn> listCols = GetDataColumn(row, workBookPart);
                        dataTable.Columns.AddRange(listCols.ToArray());
                    }
                    else
                    {
                        //Excel第二行同时为DataTable的第一行数据
                        DataRow dataRow = GetDataRow(row, dataTable, workBookPart);
                        if (dataRow != null)
                        {
                            dataTable.Rows.Add(dataRow);
                        }
                    }
                }
                return dataTable;
            }
    
            /// <summary>
            /// 获取数字类型格式集合
            /// </summary>
            /// <param name="workBookPart"></param>
            /// <returns></returns>
            private List<string> GetNumberFormatsStyle(WorkbookPart workBookPart)
            {
                List<string> dicStyle = new List<string>();
                Stylesheet styleSheet = workBookPart.WorkbookStylesPart.Stylesheet;
                var test = styleSheet.NumberingFormats;
                if (test == null) return null;
                OpenXmlElementList list = styleSheet.NumberingFormats.ChildElements;//获取NumberingFormats样式集合
    
                foreach (var element in list)//格式化节点
                {
                    if (element.HasAttributes)
                    {
                        using (OpenXmlReader reader = OpenXmlReader.Create(element))
                        {
                            if (reader.Read())
                            {
                                if (reader.Attributes.Count > 0)
                                {
                                    string numFmtId = reader.Attributes[0].Value;//格式化ID
                                    string formatCode = reader.Attributes[1].Value;//格式化Code
                                    dicStyle.Add(formatCode);//将格式化Code写入List集合
                                }
                            }
                        }
                    }
                }
                return dicStyle;
            }
    
            /// <summary>
            /// 获得DataColumn
            /// </summary>
            /// <param name="row"></param>
            /// <param name="workBookPart"></param>
            /// <returns></returns>
            private List<DataColumn> GetDataColumn(Row row, WorkbookPart workBookPart)
            {
                List<DataColumn> listCols = new List<DataColumn>();
                foreach (Cell cell in row)
                {
                    string cellValue = GetCellValue(cell, workBookPart);
                    DataColumn col = new DataColumn(cellValue);
                    listCols.Add(col);
                }
                return listCols;
            }
    
            /// <summary>
            /// 将sheet页中的一行数据转换成DataRow
            /// </summary>
            /// <param name="row"></param>
            /// <param name="dateTable"></param>
            /// <param name="workBookPart"></param>
            /// <returns></returns>
            private DataRow GetDataRow(Row row, DataTable dateTable, WorkbookPart workBookPart)
            {
                //读取Excel中数据,一一读取单元格,若整行为空则忽视该行
                DataRow dataRow = dateTable.NewRow();
                IEnumerable<Cell> cells = row.Elements<Cell>();
    
                int cellIndex = 0;//单元格索引
                int nullCellCount = cellIndex;//空行索引
                foreach (Cell cell in row)
                {
                    string cellVlue = GetCellValue(cell, workBookPart);
                    if (string.IsNullOrEmpty(cellVlue))
                    {
                        nullCellCount++;
                    }
    
                    dataRow[cellIndex] = cellVlue;
                    cellIndex++;
                }
                if (nullCellCount == cellIndex)//剔除空行
                {
                    dataRow = null;//一行中单元格索引和空行索引一样
                }
                return dataRow;
            }
    
            /// <summary>
            /// 获得单元格数据值
            /// </summary>
            /// <param name="cell"></param>
            /// <param name="workBookPart"></param>
            /// <returns></returns>
            public string GetCellValue(Cell cell, WorkbookPart workBookPart)
            {
                string cellValue = string.Empty;
                if (cell.ChildElements.Count == 0)//Cell节点下没有子节点
                {
                    return cellValue;
                }
                string cellRefId = cell.CellReference.InnerText;//获取引用相对位置
                string cellInnerText = cell.CellValue.InnerText;//获取Cell的InnerText
                cellValue = cellInnerText;//指定默认值(其实用来处理Excel中的数字)
    
                //获取WorkbookPart中NumberingFormats样式集合
                //List<string> dicStyles = GetNumberFormatsStyle(workBookPart);
                //获取WorkbookPart中共享String数据
                SharedStringTable sharedTable = workBookPart.SharedStringTablePart.SharedStringTable;
    
                try
                {
                    EnumValue<CellValues> cellType = cell.DataType;//获取Cell数据类型
                    if (cellType != null)//Excel对象数据
                    {
                        switch (cellType.Value)
                        {
                            case CellValues.SharedString://字符串
                                //获取该Cell的所在的索引
                                int cellIndex = int.Parse(cellInnerText);
                                cellValue = sharedTable.ChildElements[cellIndex].InnerText;
                                break;
                            case CellValues.Boolean://布尔
                                cellValue = (cellInnerText == "1") ? "TRUE" : "FALSE";
                                break;
                            case CellValues.Date://日期
                                cellValue = Convert.ToDateTime(cellInnerText).ToString();
                                break;
                            case CellValues.Number://数字
                                cellValue = Convert.ToDecimal(cellInnerText).ToString();
                                break;
                            default: cellValue = cellInnerText; break;
                        }
                    }
                    else//格式化数据
                    {
                        #region 根据Excel单元格格式设置数据类型,该部分代码有误,暂未处理
                        /*
                        if (dicStyles.Count > 0 && cell.StyleIndex != null)//对于数字,cell.StyleIndex==null
                        {
                            int styleIndex = Convert.ToInt32(cell.StyleIndex.Value);
                            string cellStyle = dicStyles[styleIndex - 1];//获取该索引的样式
                            if (cellStyle.Contains("yyyy") || cellStyle.Contains("h")
                                || cellStyle.Contains("dd") || cellStyle.Contains("ss"))
                            {
                                //如果为日期或时间进行格式处理,去掉“;@”
                                cellStyle = cellStyle.Replace(";@", "");
                                while (cellStyle.Contains("[") && cellStyle.Contains("]"))
                                {
                                    int otherStart = cellStyle.IndexOf('[');
                                    int otherEnd = cellStyle.IndexOf("]");
    
                                    cellStyle = cellStyle.Remove(otherStart, otherEnd - otherStart + 1);
                                }
                                double doubleDateTime = double.Parse(cellInnerText);
                                DateTime dateTime = DateTime.FromOADate(doubleDateTime);//将Double日期数字转为日期格式
                                if (cellStyle.Contains("m")) { cellStyle = cellStyle.Replace("m", "M"); }
                                if (cellStyle.Contains("AM/PM")) { cellStyle = cellStyle.Replace("AM/PM", ""); }
                                cellValue = dateTime.ToString(cellStyle);//不知道为什么Excel 2007中格式日期为yyyy/m/d
                            }
                            else//其他的货币、数值
                            {
                                cellStyle = cellStyle.Substring(cellStyle.LastIndexOf('.') - 1).Replace("\", "");
                                decimal decimalNum = decimal.Parse(cellInnerText);
                                cellValue = decimal.Parse(decimalNum.ToString(cellStyle)).ToString();
                            }
                        }
                        */
                        #endregion
                    }
                }
                catch
                {
                    //string expMessage = string.Format("Excel中{0}位置数据有误,请确认填写正确!", cellRefId);
                    //throw new Exception(expMessage);
                    cellValue = "N/A";
                }
                return cellValue;
            }
    
            /// <summary>
            /// 获得sheet页集合
            /// </summary>
            /// <param name="filePath"></param>
            /// <returns></returns>
            private List<string> GetExcelSheetNames(string filePath)
            {
                string sheetName = string.Empty;
                List<string> sheetNames = new List<string>();//所有Sheet表名
                using (SpreadsheetDocument spreadDocument = SpreadsheetDocument.Open(filePath, false))
                {
                    WorkbookPart workBook = spreadDocument.WorkbookPart;
                    Stream stream = workBook.GetStream(FileMode.Open);
                    XmlDocument xmlDocument = new XmlDocument();
                    xmlDocument.Load(stream);
    
                    XmlNamespaceManager xmlNSManager = new XmlNamespaceManager(xmlDocument.NameTable);
                    xmlNSManager.AddNamespace("default", xmlDocument.DocumentElement.NamespaceURI);
                    XmlNodeList nodeList = xmlDocument.SelectNodes("//default:sheets/default:sheet", xmlNSManager);
    
                    foreach (XmlNode node in nodeList)
                    {
                        sheetName = node.Attributes["name"].Value;
                        sheetNames.Add(sheetName);
                    }
                }
                return sheetNames;
            }
    
            #region SaveCell
            private void InsertTextCellValue(Worksheet worksheet, string column, uint row, string value)
            {
                Cell cell = ReturnCell(worksheet, column, row);
                CellValue v = new CellValue();
                v.Text = value;
                cell.AppendChild(v);
                cell.DataType = new EnumValue<CellValues>(CellValues.String);
                worksheet.Save();
            }
            private void InsertNumberCellValue(Worksheet worksheet, string column, uint row, string value)
            {
                Cell cell = ReturnCell(worksheet, column, row);
                CellValue v = new CellValue();
                v.Text = value;
                cell.AppendChild(v);
                cell.DataType = new EnumValue<CellValues>(CellValues.Number);
                worksheet.Save();
            }
            private static Cell ReturnCell(Worksheet worksheet, string columnName, uint row)
            {
                Row targetRow = ReturnRow(worksheet, row);
    
                if (targetRow == null)
                    return null;
    
                return targetRow.Elements<Cell>().Where(c =>
                   string.Compare(c.CellReference.Value, columnName + row,
                   true) == 0).First();
            }
            private static Row ReturnRow(Worksheet worksheet, uint row)
            {
                return worksheet.GetFirstChild<SheetData>().
                Elements<Row>().Where(r => r.RowIndex == row).First();
            }
            #endregion
    
            #endregion
    
    
            #region 写入Excel
            /// <summary>
            /// 在指定路径创建SpreadsheetDocument文档
            /// </summary>
            /// <param name="filePath"></param>
            /// <returns></returns>
            private SpreadsheetDocument CreateParts(string filePath)
            {
                SpreadsheetDocument document = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook);
    
                WorkbookPart workbookPart = document.AddWorkbookPart();
    
                workbookPart.Workbook = new Workbook();
    
                return document;
            }
    
            /// <summary>
            /// 创建WorksheetPart
            /// </summary>
            /// <param name="workbookPart"></param>
            /// <param name="sheetName"></param>
            /// <returns></returns>
            private WorksheetPart CreateWorksheet(WorkbookPart workbookPart, string sheetName)
            {
                WorksheetPart newWorksheetPart = workbookPart.AddNewPart<WorksheetPart>();
    
                newWorksheetPart.Worksheet = new Worksheet(new SheetData());
    
                newWorksheetPart.Worksheet.Save();
    
                Sheets sheets = workbookPart.Workbook.GetFirstChild<Sheets>();
                if (sheets == null)
                    sheets = workbookPart.Workbook.AppendChild<Sheets>(new Sheets());
    
                string relationshipId = workbookPart.GetIdOfPart(newWorksheetPart);
    
                uint sheetId = 1;
    
                if (sheets.Elements<Sheet>().Count() > 0)
                {//确定sheet的唯一编号
                    sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
                }
                if (string.IsNullOrEmpty(sheetName))
                {
                    sheetName = "Sheet" + sheetId;
                }
    
                Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = sheetName };
                sheets.Append(sheet);
    
                workbookPart.Workbook.Save();
    
                return newWorksheetPart;
            }
    
            /// <summary>
            /// 创建sheet样式
            /// </summary>
            /// <param name="workbookPart"></param>
            /// <returns></returns>
            private Stylesheet CreateStylesheet(WorkbookPart workbookPart)
            {
                Stylesheet stylesheet = null;
    
                if (workbookPart.WorkbookStylesPart != null)
                {
                    stylesheet = workbookPart.WorkbookStylesPart.Stylesheet;
                    if (stylesheet != null)
                    {
                        return stylesheet;
                    }
                }
                workbookPart.AddNewPart<WorkbookStylesPart>("Style");
                workbookPart.WorkbookStylesPart.Stylesheet = new Stylesheet();
                stylesheet = workbookPart.WorkbookStylesPart.Stylesheet;
    
                stylesheet.Fonts = new Fonts()
                {
                    Count = (UInt32Value)3U
                };
    
                //fontId =0,默认样式
                Font fontDefault = new Font(
                                             new FontSize() { Val = 11D },
                                             new FontName() { Val = "Calibri" },
                                             new FontFamily() { Val = 2 },
                                             new FontScheme() { Val = FontSchemeValues.Minor });
    
                stylesheet.Fonts.Append(fontDefault);
    
                //fontId =1,标题样式
                Font fontTitle = new Font(new FontSize() { Val = 15D },
                                             new Bold() { Val = true },
                                             new FontName() { Val = "Calibri" },
                                             new FontFamily() { Val = 2 },
                                             new FontScheme() { Val = FontSchemeValues.Minor });
                stylesheet.Fonts.Append(fontTitle);
    
                //fontId =2,列头样式
                Font fontHeader = new Font(new FontSize() { Val = 13D },
                                  new Bold() { Val = true },
                                  new FontName() { Val = "Calibri" },
                                  new FontFamily() { Val = 2 },
                                  new FontScheme() { Val = FontSchemeValues.Minor });
                stylesheet.Fonts.Append(fontHeader);
    
                //fillId,0总是None,1总是gray125,自定义的从fillid =2开始
                stylesheet.Fills = new Fills()
                {
                    Count = (UInt32Value)3U
                };
    
                //fillid=0
                Fill fillDefault = new Fill(new PatternFill() { PatternType = PatternValues.None });
                stylesheet.Fills.Append(fillDefault);
    
                //fillid=1
                Fill fillGray = new Fill();
                PatternFill patternFillGray = new PatternFill()
                {
                    PatternType = PatternValues.Gray125
                };
                fillGray.Append(patternFillGray);
                stylesheet.Fills.Append(fillGray);
    
                //fillid=2
                Fill fillYellow = new Fill();
                PatternFill patternFillYellow = new PatternFill(new ForegroundColor() { Rgb = new HexBinaryValue() { Value = "FFFFFF00" } })
                {
                    PatternType = PatternValues.Solid
                };
                fillYellow.Append(patternFillYellow);
                stylesheet.Fills.Append(fillYellow);
    
                stylesheet.Borders = new Borders()
                {
                    Count = (UInt32Value)2U
                };
    
                //borderID=0
                Border borderDefault = new Border(new LeftBorder(), new RightBorder(), new TopBorder() { }, new BottomBorder(), new DiagonalBorder());
                stylesheet.Borders.Append(borderDefault);
    
                //borderID=1
                Border borderContent = new Border(
                    new LeftBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
                    new RightBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
                    new TopBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
                    new BottomBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
                    new DiagonalBorder()
                    );
                stylesheet.Borders.Append(borderContent);
    
                stylesheet.CellFormats = new CellFormats();
                stylesheet.CellFormats.Count = 3;
    
                //styleIndex =0U
                CellFormat cfDefault = new CellFormat();
                cfDefault.Alignment = new Alignment();
                cfDefault.NumberFormatId = 0;
                cfDefault.FontId = 0;
                cfDefault.BorderId = 0;
                cfDefault.FillId = 0;
                cfDefault.ApplyAlignment = true;
                cfDefault.ApplyBorder = true;
                stylesheet.CellFormats.Append(cfDefault);
    
                //styleIndex =1U
                CellFormat cfTitle = new CellFormat();
                cfTitle.Alignment = new Alignment();
                cfTitle.NumberFormatId = 0;
                cfTitle.FontId = 1;
                cfTitle.BorderId = 1;
                cfTitle.FillId = 0;
                cfTitle.ApplyBorder = true;
                cfTitle.ApplyAlignment = true;
                cfTitle.Alignment.Horizontal = HorizontalAlignmentValues.Center;
                stylesheet.CellFormats.Append(cfTitle);
    
                //styleIndex =2U
                CellFormat cfHeader = new CellFormat();
                cfHeader.Alignment = new Alignment();
                cfHeader.NumberFormatId = 0;
                cfHeader.FontId = 2;
                cfHeader.BorderId = 1;
                cfHeader.FillId = 2;
                cfHeader.ApplyAlignment = true;
                cfHeader.ApplyBorder = true;
                cfHeader.ApplyFill = true;
                cfHeader.Alignment.Horizontal = HorizontalAlignmentValues.Center;
                stylesheet.CellFormats.Append(cfHeader);
    
                //styleIndex =3U
                CellFormat cfContent = new CellFormat();
                cfContent.Alignment = new Alignment();
                cfContent.NumberFormatId = 0;
                cfContent.FontId = 0;
                cfContent.BorderId = 1;
                cfContent.FillId = 0;
                cfContent.ApplyAlignment = true;
                cfContent.ApplyBorder = true;
                stylesheet.CellFormats.Append(cfContent);
    
                workbookPart.WorkbookStylesPart.Stylesheet.Save();
                return stylesheet;
            }
    
            /// <summary>
            /// 创建文本单元格,Cell的内容均视为文本
            /// </summary>
            /// <param name="columnIndex"></param>
            /// <param name="rowIndex"></param>
            /// <param name="cellValue"></param>
            /// <param name="styleIndex"></param>
            /// <returns></returns>
            private Cell CreateTextCell(int columnIndex, int rowIndex, object cellValue, Nullable<uint> styleIndex)
            {
                Cell cell = new Cell();
    
                cell.DataType = CellValues.InlineString;
    
                cell.CellReference = GetCellReference(columnIndex) + rowIndex;
    
                if (styleIndex.HasValue)
                    cell.StyleIndex = styleIndex.Value;
    
                InlineString inlineString = new InlineString();
                Text t = new Text();
    
                t.Text = cellValue.ToString();
                inlineString.AppendChild(t);
                cell.AppendChild(inlineString);
    
                return cell;
            }
    
            /// <summary>
            /// 创建值单元格,Cell会根据单元格值的类型
            /// </summary>
            /// <param name="columnIndex"></param>
            /// <param name="rowIndex"></param>
            /// <param name="cellValue"></param>
            /// <param name="styleIndex"></param>
            /// <returns></returns>
            private Cell CreateValueCell(int columnIndex, int rowIndex, object cellValue, Nullable<uint> styleIndex)
            {
                Cell cell = new Cell();
                cell.CellReference = GetCellReference(columnIndex) + rowIndex;
                CellValue value = new CellValue();
                value.Text = cellValue.ToString();
    
                //apply the cell style if supplied
                if (styleIndex.HasValue)
                    cell.StyleIndex = styleIndex.Value;
    
                cell.AppendChild(value);
    
                return cell;
            }
    
            /// <summary>
            /// 获取行引用,如A1
            /// </summary>
            /// <param name="colIndex"></param>
            /// <returns></returns>
            private string GetCellReference(int colIndex)
            {
                int dividend = colIndex;
                string columnName = String.Empty;
                int modifier;
    
                while (dividend > 0)
                {
                    modifier = (dividend - 1) % 26;
                    columnName =
                        Convert.ToChar(65 + modifier).ToString() + columnName;
                    dividend = (int)((dividend - modifier) / 26);
                }
                return columnName;
            }
    
            /// <summary>
            /// 创建行数据,不同类型使用不同的styleIndex
            /// </summary>
            /// <param name="dataRow"></param>
            /// <param name="rowIndex"></param>
            /// <returns></returns>
            private Row CreateDataRow(DataRow dataRow, int rowIndex)
            {
                Row row = new Row
                {
                    RowIndex = (UInt32)rowIndex
                };
    
                //Nullable<uint> styleIndex = null;
                double doubleValue;
                int intValue;
                DateTime dateValue;
                decimal decValue;
    
                for (int i = 0; i < dataRow.Table.Columns.Count; i++)
                {
                    Cell dataCell;
                    if (DateTime.TryParse(dataRow[i].ToString(), out dateValue) && dataRow[i].GetType() == typeof(DateTime))
                    {
                        dataCell = CreateTextCell(i + 1, rowIndex, dataRow[i], 3u);
                        //dataCell.DataType = CellValues.Date;
                    }
                    else if (decimal.TryParse(dataRow[i].ToString(), out decValue) && dataRow[i].GetType() == typeof(decimal))
                    {
                        dataCell = CreateValueCell(i + 1, rowIndex, decValue, 3u);
                    }
                    else if (int.TryParse(dataRow[i].ToString(), out intValue) && dataRow[i].GetType() == typeof(int))
                    {
                        dataCell = CreateValueCell(i + 1, rowIndex, intValue, 3u);
                    }
                    else if (Double.TryParse(dataRow[i].ToString(), out doubleValue) && dataRow[i].GetType() == typeof(double))
                    {
                        dataCell = CreateValueCell(i + 1, rowIndex, doubleValue, 3u);
                    }
                    else
                    {
                        dataCell = CreateTextCell(i + 1, rowIndex, dataRow[i], 3u);
                    }
    
                    row.AppendChild(dataCell);
                    //styleIndex = null;
                }
                return row;
            }
    
            /// <summary>
            /// 将DataTable的列名称导入Excel
            /// </summary>
            /// <param name="dt"></param>
            /// <param name="sheetData"></param>
            private void CreateTableHeader(DataTable dt, SheetData sheetData)
            {
                Row header = new Row
                {
                    RowIndex = (UInt32)1
                };
                int colCount = dt.Columns.Count;
                for(int i = 0; i < colCount; i++)
                {
                    string colName = dt.Columns[i].ColumnName;
                    Cell dataCell = CreateTextCell( i + 1, 1, colName, 3u);
                    header.AppendChild(dataCell);
                }
                //Row contentRow = CreateDataRow(header, 1);
                sheetData.AppendChild(header);
            }
    
            /// <summary>
            /// 将DataTable的数据导入Excel
            /// </summary>
            /// <param name="dt"></param>
            /// <param name="sheetData"></param>
            private void InsertDataIntoSheet(DataTable dt, SheetData sheetData)
            {
                //SheetData sheetData = newWorksheetPart.Worksheet.GetFirstChild<SheetData>();
    
                //CreateTableHeader(dt, sheetData);
    
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    Row contentRow = CreateDataRow(dt.Rows[i], i + 2);
                    sheetData.AppendChild(contentRow);
                }
                return;
            }
    
            /// <summary>
            /// 创建一个SharedStringTablePart(相当于各Sheet共用的存放字符串的容器)
            /// </summary>
            /// <param name="workbookPart"></param>
            /// <returns></returns>
            private SharedStringTablePart CreateSharedStringTablePart(WorkbookPart workbookPart)
            {
                SharedStringTablePart shareStringPart = null;
                if (workbookPart.GetPartsOfType<SharedStringTablePart>().Count() > 0)
                {
                    shareStringPart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
                }
                else
                {
                    shareStringPart = workbookPart.AddNewPart<SharedStringTablePart>();
                }
                return shareStringPart;
            }
    
            /// <summary>
            /// 导出Excel,执行函数
            /// </summary>
            /// <param name="dt"></param>
            /// <param name="filePath"></param>
            public void DataTableToExcel(DataTable dt, string filePath)
            {
                try
                {
                    using (SpreadsheetDocument document = CreateParts(filePath))
                    {
                        WorksheetPart worksheetPart = CreateWorksheet(document.WorkbookPart, dt.TableName);
    
                        SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
    
                        Stylesheet styleSheet = CreateStylesheet(document.WorkbookPart);
    
                        //InsertTableTitle(parameter.SheetName, sheetData, styleSheet);
    
                        // MergeTableTitleCells(dt.Columns.Count, worksheetPart.Worksheet);
    
                        CreateTableHeader(dt, sheetData);
    
                        InsertDataIntoSheet(dt, sheetData);
    
                        SharedStringTablePart sharestringTablePart = CreateSharedStringTablePart(document.WorkbookPart);
                        sharestringTablePart.SharedStringTable = new SharedStringTable();
    
                        sharestringTablePart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text("ExcelReader")));
                        sharestringTablePart.SharedStringTable.Save();
                    }
                    //result = 0;
                }
                catch (Exception ex)
                {
                    //iSession.AddError(ex);
                    //result = error_result_prefix - 99;
                }
                //return result;
            }
    
            #endregion
        }
    View Code
  • 相关阅读:
    每日一招:个股五种见底特征
    中国互联网或将被世界淘汰 !
    了解这23种设计模式
    用Nikto探测一个网站所用到的技术
    javax.crypto.BadPaddingException: Given final block not properly padded
    java.net.UnknownHostException: promote.cache-dns.local: unknown error
    CentOS 7 Rescure
    最小化安装的CentOS7挂载ntfs格式的U盘
    CentOS 7 最小化安装的无线网络配置
    Mysql Specified key was too long; max key length is 767 bytes
  • 原文地址:https://www.cnblogs.com/zhchsh/p/5131020.html
Copyright © 2020-2023  润新知