瀏覽代碼

修复Excel读取数据忽略空白单元格BUG

宝臣 王 3 月之前
父節點
當前提交
5ac541686b
共有 1 個文件被更改,包括 72 次插入40 次删除
  1. 72 40
      UniformMaterialManagementSystem/Utils/ExcelUtil.cs

+ 72 - 40
UniformMaterialManagementSystem/Utils/ExcelUtil.cs

@@ -4,6 +4,7 @@ using DocumentFormat.OpenXml.Spreadsheet;
 
 using System.Data;
 using System.IO;
+using System.Text.RegularExpressions;
 
 namespace UniformMaterialManagementSystem.Utils
 {
@@ -19,7 +20,7 @@ namespace UniformMaterialManagementSystem.Utils
             var isFileLocked = IsFileLocked(filePath);
             if (isFileLocked)
             {
-                var destFilePath =  $"Temp\\{DateTime.Now.Ticks}.xls";
+                var destFilePath = $"Temp\\{DateTime.Now.Ticks}.xls";
                 File.Copy(filePath, destFilePath);
                 filePath = destFilePath;
             }
@@ -27,51 +28,51 @@ namespace UniformMaterialManagementSystem.Utils
             var dataTable = new DataTable();
             using var spreadSheetDocument = SpreadsheetDocument.Open(filePath, false);
 
+            var workbookPart = spreadSheetDocument.WorkbookPart;
+            var worksheetPart = workbookPart?.WorksheetParts.First();
+            var sheetData = worksheetPart?.Worksheet.Elements<SheetData>().First();
 
-            var workbookPart = spreadSheetDocument.WorkbookPart ?? spreadSheetDocument.AddWorkbookPart();
-            var sheets = workbookPart.Workbook.GetFirstChild<Sheets>()?.Elements<Sheet>();
-            string relationshipId = sheets.First().Id.Value = sheets.First().Id.Value;
-            WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById(relationshipId);
-            //var worksheetPart = workbookPart.WorksheetParts.First();
-
-            var reader = OpenXmlReader.Create(worksheetPart);
-            //string[]? headers = null;
-            var rowIndex = 0;
-
-            while (reader.Read())
+            if (sheetData != null)
             {
-                if (reader.ElementType != typeof(Row)) continue;
-                reader.ReadFirstChild();
+                var rows = sheetData.Descendants<Row>().ToList();
 
-                var dataRow = dataTable.NewRow();
-                var columnIndex = 0;
-
-                do
+                for (var i = 0; i < rows.Count; i++)
                 {
-                    if (reader.ElementType != typeof(Cell)) continue;
-                    if (reader.LoadCurrentElement() is Cell cell)
+                    var row = rows[i];
+                    var dataRow = dataTable.NewRow();
+                    var currentColumnIndex = 0;
+
+                    var cells = row.Descendants<Cell>();
+                    foreach (var cell in cells)
                     {
                         var cellValue = GetCellValue(cell, workbookPart);
-
-                        if (rowIndex == 0)
+                        if (i == 0)
                         {
-                            dataTable.Columns.Add(cellValue);
-                            //headers ??= new string[dataTable.Columns.Count];
-                            //headers[columnIndex] = cellValue;
+                            if (dataTable.Columns.Count <= currentColumnIndex)
+                            {
+                                dataTable.Columns.Add(cellValue);
+                            }
+
+                            dataRow.Delete();
                         }
                         else
                         {
-                            dataRow[columnIndex] = cellValue;
-                        }
-                    }
+                            var cellColumnIndex = GetColumnIndex(cell);
 
-                    columnIndex++;
-                } while (reader.ReadNextSibling());
+                            for (; currentColumnIndex < cellColumnIndex; currentColumnIndex++)
+                            {
+                                dataRow[currentColumnIndex] = DBNull.Value;
+                            }
 
-                if (rowIndex != 0)
-                    dataTable.Rows.Add(dataRow);
+                            dataRow[currentColumnIndex] = cellValue;
+                        }
+
+                        currentColumnIndex++;
+                    }
 
-                rowIndex++;
+                    if (i != 0)
+                        dataTable.Rows.Add(dataRow);
+                }
             }
 
             if (isFileLocked)
@@ -82,27 +83,58 @@ namespace UniformMaterialManagementSystem.Utils
             return dataTable;
         }
 
-        private static string GetCellValue(CellType cell, WorkbookPart workbookPart)
+        private static string GetCellValue(CellType cell, WorkbookPart? workbookPart)
         {
             var value = cell.InnerText;
             if (cell.DataType == null || cell.DataType.Value != CellValues.SharedString) return value;
 
-            if (workbookPart.SharedStringTablePart != null)
+            if (workbookPart?.SharedStringTablePart != null)
                 return workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>()
                     .ElementAt(int.Parse(value)).InnerText;
 
             return value;
         }
 
+        public static int GetColumnIndex(Cell? cell)
+        {
+            var columnName = string.Empty;
+
+            if (cell != null)
+            {
+                var cellReference = cell.CellReference?.ToString();
+
+                if (!string.IsNullOrEmpty(cellReference))
+                    columnName = Regex.Match(cellReference, @"[A-Z]{1,3}").Value;
+            }
+
+            if (string.IsNullOrEmpty(columnName))
+                throw new ArgumentException("Column name was not defined.", nameof(columnName));
+
+            if (!Regex.IsMatch(columnName, @"^[A-Z]{1,3}$"))
+                throw new ArgumentException("Column name is not valid.", nameof(columnName));
+
+            var index = 0;
+            var pow = 1;
+
+            for (var i = columnName.Length - 1; i >= 0; i--)
+            {
+                index += (columnName[i] - 'A' + 1) * pow;
+                pow *= 26;
+            }
+
+            if (index >= 16384)
+                throw new IndexOutOfRangeException("Index of provided column name (" + index + ") exceeds max range (16384).");
+
+            return index - 1;
+        }
+
         private static bool IsFileLocked(string filePath)
         {
             try
             {
-                using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None))
-                {
-                    // 如果能够成功打开文件,说明文件未被占用
-                    return false;
-                }
+                using FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None);
+                // 如果能够成功打开文件,说明文件未被占用
+                return false;
             }
             catch (IOException)
             {