• C# OpenXml组件


      public class OpenXmlHelper
        {
            #region 导入
            /// <summary>
            /// 按照给定的地址读取Excel转换成DataTable
            /// </summary>
            /// <param name="path">路径</param>
            /// <param name="page">页码</param>
            /// <param name="pagesize">页行数</param>
            /// <param name="sheetName">Excel的Sheet名;默认第一个Sheet</param>
            /// <param name="index">列头行;默认第一列</param>
            /// <returns></returns>
            /// OpenXml只支持Excel2007版后的.xlsx
            public static DataTable Read(string path, int page = 0, int pagesize = 0, string sheetName = null, int index = 1)
            {
                try
                {
                    DataTable dt = new DataTable();
                    if (!path.ToLower().Trim().EndsWith(".xlsx"))
                    {
                        throw new Exception("OpenXml组件只支持Office Excel2007版后的.xlsx格式文件");
                    }
                    using (SpreadsheetDocument document = SpreadsheetDocument.Open(path, false))
                    {
                        //打开Stream
                        IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>();
                        if (!string.IsNullOrEmpty(sheetName))
                        {
                            sheets = sheets.Where(s => s.Name.ToString().ToLower() == sheetName.ToLower());
                            if (sheets.Count() == 0)
                            {
                                throw new Exception("没有找到该Sheet");
                            }
                        }
                        WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);
                        //获取Excel中共享数据
                        SharedStringTable stringTable = document.WorkbookPart.SharedStringTablePart.SharedStringTable;
                        IEnumerable<Row> rows = worksheetPart.Worksheet.Descendants<Row>();//获得Excel中得数据行
                        foreach (Row row in rows)
                        {
                            if (row.RowIndex == index)//Excel的列名列
                            {
                                GetDataColumn(row, stringTable, ref dt);
                                break;
                            }
                        }
                        if (page != 0 && pagesize != 0)
                        {
                            rows = rows.Skip((pagesize * (page-1))+1).Take(pagesize);
                            foreach (Row row in rows)
                            {
                                if (row.RowIndex != index)
                                {
                                    GetDataRow(row, stringTable, ref dt, document.WorkbookPart);//Excel中行数大于列头的都作为数据列处理
                                }
                            }
                        }
                        else
                        {

                            foreach (Row row in rows)
                            {
                                if (row.RowIndex != index) {
                                    GetDataRow(row, stringTable, ref dt, document.WorkbookPart);//Excel中行数大于列头的都作为数据列处理
                                }
                               
                            }
                        }
                        return dt;
                    }
                }
                catch (Exception ex)
                {

                    throw ex;
                }

            }
            /// <summary>
            /// Excel数据列总行数(不包括列头)
            /// </summary>
            /// <param name="path"></param>
            /// <param name="sheetName"></param>
            /// <param name="index"></param>
            /// <returns></returns>
            public static int GetExcelCount(string path, string sheetName = null, int index = 1)
            {
                try
                {
                    DataTable dt = new DataTable();
                    if (!path.ToLower().Trim().EndsWith(".xlsx"))
                    {
                        throw new Exception("OpenXml组件只支持Office Excel2007版后的.xlsx格式文件");
                    }
                    using (SpreadsheetDocument document = SpreadsheetDocument.Open(path, false))
                    {
                        //打开Stream
                        IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>();
                        if (!string.IsNullOrEmpty(sheetName))
                        {
                            sheets = sheets.Where(s => s.Name.ToString().ToLower() == sheetName.ToLower());
                            if (sheets.Count() == 0)
                            {
                                throw new Exception("没有找到该Sheet");
                            }
                        }
                        WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);
                        //获取Excel中共享数据
                        SharedStringTable stringTable = document.WorkbookPart.SharedStringTablePart.SharedStringTable;
                        IEnumerable<Row> rows = worksheetPart.Worksheet.Descendants<Row>();//获得Excel中得数据行
                        return rows.Count() - 1;
                    }
                }
                catch (Exception ex)
                {

                    throw ex;
                }
            }
            /// <summary>
            /// 获取Excel原始列下标
            /// </summary>
            /// <param name="str">原始列名</param>
            /// <returns></returns>
            private static int GetIndexNumber(string value)
            {
                if (string.IsNullOrEmpty(value))
                {
                    return -1;
                }
                char[] chars = value.ToLower().ToCharArray();
                int index = 0;
                for (int i = 0; i < chars.Length; i++)
                {
                    index += ((int)chars[i] - (int)'a' + 1) * (int)Math.Pow(26, chars.Length - i - 1);
                }
                return index - 1;
            }

            /// <summary>
            /// 构建DataTable的列
            /// </summary>
            /// <param name="row">OpenXML定义的Row对象</param>
            /// <param name="stringTablePart"></param>
            /// <param name="dt">须要返回的DataTable对象</param>
            /// <returns></returns>
            private static void GetDataColumn(Row row, SharedStringTable stringTable, ref DataTable dt)
            {
                DataColumn col = new DataColumn();
                Dictionary<string, int> columnCount = new Dictionary<string, int>();
                foreach (Cell cell in row)
                {
                    string cellVal = GetValue(cell, stringTable);
                    col = new DataColumn(cellVal);
                    if (IsContainsColumn(dt, col.ColumnName))
                    {
                        if (!columnCount.ContainsKey(col.ColumnName))
                            columnCount.Add(col.ColumnName, 0);
                        col.ColumnName = col.ColumnName + (columnCount[col.ColumnName]++);
                    }
                    dt.Columns.Add(col);
                }
            }
            /// <summary>
            /// 构建DataTable的每一行数据,并返回该Datatable
            /// </summary>
            /// <param name="row">OpenXML的行</param>
            /// <param name="stringTablePart"></param>
            /// <param name="dt">DataTable</param>
            private static void GetDataRow(Row row, SharedStringTable stringTable, ref DataTable dt, WorkbookPart workbookPart)
            {
                //读取数据
                DataRow dr = dt.NewRow();
                int number = 0;
                foreach (Cell cell in row)
                {
                    //获取Excel列头
                    var column = Regex.Replace(cell.CellReference.Value, "[0-9]", "");
                    //列头转换成下标
                    var index = GetIndexNumber(column);
                    if (index < 0)
                    {
                        continue;
                    }
                    string cellVal = GetValue(cell, stringTable);
                    if (!string.IsNullOrEmpty(cellVal))
                    {
                        if (cell.DataType != null && (cell.DataType.Value == CellValues.SharedString || cell.DataType.Value == CellValues.String || cell.DataType.Value == CellValues.Number))
                        {
                            if (index < dt.Columns.Count)
                            {
                                switch (cell.DataType.Value)
                                {
                                    case CellValues.Boolean:
                                        dr[index] = Convert.ToBoolean(GetValue(cell, stringTable));
                                        break;
                                    case CellValues.Date:
                                        dr[index] = Convert.ToDateTime(GetValue(cell, stringTable));
                                        break;
                                    default:
                                        dr[index] = Convert.ToString(GetValue(cell, stringTable));
                                        break;
                                }

                            }
                        }
                        else
                        {
                            //日期格式
                            if (workbookPart.WorkbookStylesPart!=null/*cell.StyleIndex != null*/)
                            {
                                var styleSheet = workbookPart.WorkbookStylesPart.Stylesheet;
                                if (styleSheet!= null) {
                                    CellFormat cellFormat = (CellFormat)styleSheet.CellFormats.ChildElements[(int)cell.StyleIndex.Value];
                                    int formatId = (int)cellFormat.NumberFormatId.Value;
                                    if (formatId == 177)
                                    {
                                        dr[index] = DateTime.FromOADate(double.Parse(GetValue(cell, stringTable)));
                                    }
                                    //双精度浮点格式
                                    else
                                    {
                                        dr[index] = double.Parse(GetValue(cell, stringTable));

                                    }
                                }
                              
                            }
                            else
                            {
                                dr[index] = GetValue(cell, stringTable);
                            }
                        }
                    }
                    else
                    {
                        dr[index] = cellVal;
                    }

                    if (!string.IsNullOrEmpty(cellVal))
                    {
                        number++;
                    }

                }
                if (number != 0)
                {
                    dt.Rows.Add(dr);
                }
            }
            /// <summary>
            /// 获取单位格的值
            /// </summary>
            /// <param name="cell"></param>
            /// <param name="stringTablePart"></param>
            /// <returns></returns>
            private static 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 = string.Empty;
                }
                return value;
            }
            /// <summary>
            /// 判断网格是否存在列
            /// </summary>
            /// <param name="dt">网格</param>
            /// <param name="columnName">列名</param>
            /// <returns></returns>
            private static bool IsContainsColumn(DataTable dt, string columnName)
            {
                if (dt == null || columnName == null)
                {
                    return false;
                }
                return dt.Columns.Contains(columnName);
            }
            #endregion
            #region 导出
            /// <summary>
            /// 获取Excel原始Colum名称
            /// </summary>
            /// <param name="index"></param>
            /// <returns></returns>
            static string GetLetter(int index)
            {
                if (index < 0)
                {
                    throw new Exception($"参数{nameof(index)}异常");
                }
                List<string> chars = new List<string>();
                do
                {
                    if (chars.Count > 0) index--;
                    chars.Insert(0, ((char)(index % 26 + (int)'A')).ToString());
                    index = (int)((index - index % 26) / 26);
                } while (index > 0);

                return String.Join(string.Empty, chars.ToArray());
            }
            /// <summary>
            /// 添加WorkSheet
            /// </summary>
            private static WorksheetPart InsertWorksheet(WorkbookPart workbookPart, string sheetName)
            {
                //创建新的WorksheetPart
                WorksheetPart newWorksheetPart = workbookPart.AddNewPart<WorksheetPart>();
                newWorksheetPart.Worksheet = new Worksheet(new SheetData());
                newWorksheetPart.Worksheet.Save();
                //在末尾追加一个Sheets
                Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
                string relationshipId = workbookPart.GetIdOfPart(newWorksheetPart);
                Sheet sheet = new Sheet() { Id = relationshipId, SheetId = 1, Name = sheetName };
                //添加Sheet
                sheets.Append(sheet);
                workbookPart.Workbook.Save();
                return newWorksheetPart;
            }
            /// <summary>
            /// DataTable导出Excel到MemoryStream;
            ///Return File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "test.xlsx");
            ///MVC模式下返回文件流结果,参数一为流,参数二为文件类型,参数三为文件名
            /// </summary>
            /// <param name="dtSource">数据源</param>
            /// <param name="sheetName">Sheet名称</param>
            /// <returns></returns>
            public static MemoryStream ToExcelIntoMemoryStream(DataTable dtSource, string sheetName = "Sheet0")
            {
                try
                {
                    var memoryStream = new MemoryStream();
                    using (var document = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
                    {
                        var workbookPart = document.AddWorkbookPart();
                        workbookPart.Workbook = new Workbook();
                        //创建新的SharedStringTablePart
                        SharedStringTablePart shareStringPart = document.WorkbookPart.AddNewPart<SharedStringTablePart>();
                        // 添加一个WorkSheet
                        WorksheetPart worksheetPart = InsertWorksheet(workbookPart, sheetName);
                        // 添加SharedStringTable
                        shareStringPart.SharedStringTable = new SharedStringTable();
                        int rowIndex = 1;
                        int cellIndex = 0;
                        Worksheet worksheet = worksheetPart.Worksheet;
                        SheetData sheetData = worksheet.GetFirstChild<SheetData>();
                        //Excel表头列
                        SetSheetDataHeadRow(dtSource, ref shareStringPart, ref sheetData, ref rowIndex, ref cellIndex);
                        //Excel数据列
                        SetSheetDataRow(dtSource, ref shareStringPart, ref sheetData, ref rowIndex, ref cellIndex);
                        shareStringPart.SharedStringTable.Save();
                        worksheet.Save();
                        worksheetPart.Worksheet.Save();
                    }
                    memoryStream.Seek(0, SeekOrigin.Begin);
                    return memoryStream;
                }
                catch (Exception ex)
                {

                    throw ex;
                }
            }

            /// <summary>
            /// DataTable固定路径导出Excel,单个Sheet生成
            /// 指定路径
            /// </summary>
            /// <param name="excelFilePath">存储路径</param>
            /// <param name="table">数据</param>
            /// <param name="sheetName">Sheet名称</param>
            public static void ToExcelFixUrl(string excelFilePath, DataTable dtSource, string sheetName = "Sheet0")
            {
                try
                {
                    using (var document = SpreadsheetDocument.Create(excelFilePath, SpreadsheetDocumentType.Workbook))
                    {
                        var workbookPart = document.AddWorkbookPart();
                        workbookPart.Workbook = new Workbook();
                        //创建新的SharedStringTablePart
                        SharedStringTablePart shareStringPart = document.WorkbookPart.AddNewPart<SharedStringTablePart>();
                        // 添加WorkSheet
                        WorksheetPart worksheetPart = InsertWorksheet(workbookPart, sheetName);
                        // 添加SharedStringTable
                        shareStringPart.SharedStringTable = new SharedStringTable();
                        int rowIndex = 1;
                        int cellIndex = 0;
                        Worksheet worksheet = worksheetPart.Worksheet;
                        SheetData sheetData = worksheet.GetFirstChild<SheetData>();
                        //Excel表头列
                        SetSheetDataHeadRow(dtSource, ref shareStringPart, ref sheetData, ref rowIndex, ref cellIndex);
                        //Excel数据列
                        SetSheetDataRow(dtSource, ref shareStringPart, ref sheetData, ref rowIndex, ref cellIndex);
                        shareStringPart.SharedStringTable.Save();
                        worksheet.Save();
                        worksheetPart.Worksheet.Save();
                    }

                }
                catch (Exception ex)
                {

                    throw ex;
                }
            }
            /// <summary>
            /// 将DataTable的ColumnsName转换为Excel表头Row
            /// </summary>
            /// <param name="dtSource">数据</param>
            /// <param name="shareStringPart"></param>
            /// <param name="sheetData"></param>
            /// <param name="rowIndex">行下标</param>
            /// <param name="cellIndex">单元格下标/param>
            private static void SetSheetDataHeadRow(DataTable dtSource, ref SharedStringTablePart shareStringPart, ref SheetData sheetData, ref int rowIndex, ref int cellIndex)
            {
                {
                    Row row = new Row() { RowIndex = Convert.ToUInt32(rowIndex) };
                    sheetData.Append(row);
                    for (int c = 0; c < dtSource.Columns.Count; c++)
                    {

                        string cellReference = GetLetter(c) + rowIndex;
                        //SharedStringTable里,取数据也是根据SharedStringTable来取
                        shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(Convert.ToString(dtSource.Columns[c]))));
                      

                        Cell refCell = null;
                        foreach (Cell cell in row.Elements<Cell>())
                        {
                            if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
                            {
                                refCell = cell;
                                break;
                            }
                        }
                        Cell newCell = new Cell() { CellReference = cellReference };
                        row.InsertBefore(newCell, refCell);

                        newCell.CellValue = new CellValue(cellIndex++.ToString());
                        newCell.DataType = new EnumValue<CellValues>(CellValues.SharedString);

                        if (c == dtSource.Columns.Count - 1)
                        {
                            rowIndex++;
                        }
                    }

                }
            }
            /// <summary>
            /// 将DataTable的ColumnsData转换为数据Row
            /// </summary>
            /// <param name="dtSource">数据</param>
            /// <param name="shareStringPart"></param>
            /// <param name="sheetData"></param>
            /// <param name="rowIndex">行下标</param>
            /// <param name="cellIndex">单元格下标/param>
            private static void SetSheetDataRow(DataTable dtSource, ref SharedStringTablePart shareStringPart, ref SheetData sheetData, ref int rowIndex, ref int cellIndex)
            {
                {
                    //Excel的数据列生成
                    for (int r = 0; r < dtSource.Rows.Count; r++)
                    {
                        Row dataRow = new Row() { RowIndex = Convert.ToUInt32(rowIndex) };
                        sheetData.Append(dataRow);
                        for (int c = 0; c < dtSource.Columns.Count; c++)
                        {
                            string cellReference = GetLetter(c) + rowIndex;
                            shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(Convert.ToString(dtSource.Rows[r][c]))));
                         
                            Cell refCell = null;
                            foreach (Cell cell in dataRow.Elements<Cell>())
                            {
                                if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
                                {
                                    refCell = cell;
                                    break;
                                }
                            }
                            Cell newCell = new Cell() { CellReference = cellReference };
                            dataRow.InsertBefore(newCell, refCell);

                            newCell.CellValue = new CellValue(cellIndex++.ToString());
                            newCell.DataType = new EnumValue<CellValues>(CellValues.SharedString);


                        }
                        rowIndex++;
                    }
                }
            }

            #endregion
            /// <summary>
            /// list模型转换为DataTable
            /// </summary>
            /// <typeparam name="T">模型</typeparam>
            /// <param name="list">数据集合</param>
            /// <returns></returns>
            public static DataTable ToDataTable<T>(List<T> list)
            {
                if (list == null || list.Count <= 0)
                {
                    throw new Exception("参数异常");
                }
                DataTable dt = new DataTable();
                if (list.Count <= 0 || list == null)
                {
                    return dt;
                }
                //添加列名
                {
                    var type = list.First().GetType();
                    PropertyInfo[] PropertyList = type.GetProperties();
                    foreach (PropertyInfo item in PropertyList)
                    {
                        DataColumn dc = new DataColumn();
                        string name = item.Name;
                        dc.ColumnName = name;//反射类字段添加列名
                        dt.Columns.Add(dc);
                    }

                }
                //添加数据列
                foreach (var model in list)
                {
                    var type = model.GetType();
                    PropertyInfo[] PropertyList = type.GetProperties();
                    DataRow dr = dt.NewRow();
                    foreach (PropertyInfo item in PropertyList)
                    {
                        string name = item.Name;
                        string value = Convert.ToString(item.GetValue(model, null));
                        dr[name] = value;
                    }
                    dt.Rows.Add(dr);
                }
                return dt;
            }

        }

  • 相关阅读:
    iOS9--适配系列教程(原文/译文)
    电梯调度设计思路及算法
    10大高频率单词筛选
    html知识点总结
    关于博客
    Java构造器内部的多态方法
    Java初学者必学的六大Java语言要点
    Java中的length字段和length()方法
    Java学习有方法有捷径
    Java 分隔符函数split的使用注意事项
  • 原文地址:https://www.cnblogs.com/laukings/p/12935550.html
Copyright © 2020-2023  润新知