需要用到的控件为:button1 ;
openFileDialog;
dataGridView
cs
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
DataTable excelData = ReadExcelToDataTable(openFileDialog1.FileName);
if (excelData.Rows.Count > 0)
{
// 输出数据
dataGridView1.DataSource = excelData;
}
else
{
}
}
catch (Exception ex)
{
MessageBox.Show("Excel数据导入失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
public DataTable ReadExcelToDataTable(string filePath)
{
DataTable dt = new DataTable();
// 1. 打开Excel文件作为ZIP存档
using (Package excelPackage = Package.Open(filePath, FileMode.Open, FileAccess.Read))
{
// 2. 读取共享字符串表
List<string> sharedStrings = ReadSharedStrings(excelPackage);
// 3. 获取活动工作表URI
Uri sheetUri = GetActiveWorksheetUri(excelPackage);
if (sheetUri == null)
{
// 备用方案:尝试获取第一个工作表
sheetUri = GetFirstWorksheetUri(excelPackage);
if (sheetUri == null)
throw new Exception("Excel文件中未找到任何工作表");
}
// 4. 读取工作表数据
PackagePart worksheetPart = excelPackage.GetPart(sheetUri);
using (Stream worksheetStream = worksheetPart.GetStream())
using (XmlReader reader = XmlReader.Create(worksheetStream))
{
bool isFirstRow = true;
int maxColumns = 0;
// 先确定最大列数
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "row")
{
using (XmlReader rowReader = reader.ReadSubtree())
{
int colCount = 0;
while (rowReader.Read())
{
if (rowReader.NodeType == XmlNodeType.Element && rowReader.Name == "c")
{
colCount++;
}
}
maxColumns = Math.Max(maxColumns, colCount);
}
}
}
// 重置流位置
worksheetStream.Seek(0, SeekOrigin.Begin);
XmlReader reader1 = XmlReader.Create(worksheetStream);
// 创建足够多的列
for (int i = 0; i < maxColumns; i++)
{
dt.Columns.Add($"Column{i + 1}");
}
// 读取实际数据
while (reader1.Read())
{
if (reader1.NodeType == XmlNodeType.Element && reader1.Name == "row")
{
DataRow row = dt.NewRow();
int currentColIndex = 0;
using (XmlReader rowReader = reader1.ReadSubtree())
{
while (rowReader.Read())
{
if (rowReader.NodeType == XmlNodeType.Element && rowReader.Name == "c")
{
string cellReference = rowReader.GetAttribute("r"); // 如"A1"
string cellType = rowReader.GetAttribute("t");
string cellValue = string.Empty;
// 确定当前列索引
currentColIndex = GetColumnIndexFromReference(cellReference);
// 读取单元格值(如果有)
if (rowReader.ReadToDescendant("v"))
{
cellValue = rowReader.ReadElementContentAsString();
// 处理共享字符串
if (cellType == "s")
{
int index = int.Parse(cellValue);
if (index < sharedStrings.Count)
cellValue = sharedStrings[index];
}
}
// 确保列索引在范围内
if (currentColIndex >= 0 && currentColIndex < dt.Columns.Count)
{
row[currentColIndex] = cellValue;
}
}
}
}
// 填充空单元格
for (int i = 0; i < dt.Columns.Count; i++)
{
if (row[i] == null || row[i] == DBNull.Value)
{
row[i] = string.Empty;
}
}
dt.Rows.Add(row);
}
}
}
}
return dt;
}
// 辅助方法:读取共享字符串表
private List<string> ReadSharedStrings(Package excelPackage)
{
List<string> sharedStrings = new List<string>();
Uri sharedStringsUri = new Uri("/xl/sharedStrings.xml", UriKind.Relative);
if (excelPackage.PartExists(sharedStringsUri))
{
PackagePart sharedStringsPart = excelPackage.GetPart(sharedStringsUri);
using (Stream sharedStringsStream = sharedStringsPart.GetStream())
using (XmlReader reader = XmlReader.Create(sharedStringsStream))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "t")
{
string text = reader.ReadElementContentAsString();
sharedStrings.Add(text);
}
}
}
}
return sharedStrings;
}
// 辅助方法:获取活动工作表URI
private Uri GetActiveWorksheetUri(Package excelPackage)
{
// 1. 读取workbook.xml获取所有工作表信息
Uri workbookUri = new Uri("/xl/workbook.xml", UriKind.Relative);
PackagePart workbookPart = excelPackage.GetPart(workbookUri);
Dictionary<string, Tuple<string, bool>> sheets = new Dictionary<string, Tuple<string, bool>>();
using (Stream workbookStream = workbookPart.GetStream())
using (XmlReader reader = XmlReader.Create(workbookStream))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "sheet")
{
string name = reader.GetAttribute("name");
string sheetId = reader.GetAttribute("sheetId");
string state = reader.GetAttribute("state"); // 活动状态
bool isActive = (state == "visible" || string.IsNullOrEmpty(state));
sheets.Add(sheetId, Tuple.Create(name, isActive));
}
}
}
// 2. 读取workbook.xml.rels获取实际路径
Uri workbookRelsUri = new Uri("/xl/_rels/workbook.xml.rels", UriKind.Relative);
PackagePart workbookRelsPart = excelPackage.GetPart(workbookRelsUri);
Dictionary<string, string> sheetPaths = new Dictionary<string, string>();
using (Stream relsStream = workbookRelsPart.GetStream())
using (XmlReader reader = XmlReader.Create(relsStream))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "Relationship")
{
string id = reader.GetAttribute("Id");
string target = reader.GetAttribute("Target");
if (target.StartsWith("worksheets/"))
{
sheetPaths.Add(id, target);
}
}
}
}
// 3. 查找活动工作表
foreach (var sheet in sheets)
{
if (sheet.Value.Item2) // 如果是活动工作表
{
string sheetId = sheet.Key;
if (sheetPaths.ContainsKey($"rId{sheetId}"))
{
return new Uri("/xl/" + sheetPaths[$"rId{sheetId}"], UriKind.Relative);
}
}
}
// 如果没有明确标记的活动工作表,返回第一个可见工作表
foreach (var sheet in sheets)
{
string sheetId = sheet.Key;
if (sheetPaths.ContainsKey($"rId{sheetId}"))
{
return new Uri("/xl/" + sheetPaths[$"rId{sheetId}"], UriKind.Relative);
}
}
return null;
}
// 辅助方法:从单元格引用获取列索引(如"A1" -> 0)
private int GetColumnIndexFromReference(string cellReference)
{
if (string.IsNullOrEmpty(cellReference))
return -1;
string columnPart = string.Empty;
foreach (char c in cellReference)
{
if (char.IsLetter(c))
columnPart += c;
else
break;
}
if (string.IsNullOrEmpty(columnPart))
return -1;
int index = 0;
foreach (char c in columnPart)
{
index = index * 26 + (char.ToUpper(c) - 'A' + 1);
}
return index - 1; // 转为0-based索引
}
// 获取第一个工作表URI(备用方案)
private Uri GetFirstWorksheetUri(Package excelPackage)
{
Uri workbookUri = new Uri("/xl/workbook.xml", UriKind.Relative);
PackagePart workbookPart = excelPackage.GetPart(workbookUri);
using (Stream workbookStream = workbookPart.GetStream())
using (XmlReader reader = XmlReader.Create(workbookStream))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "sheet")
{
string sheetId = reader.GetAttribute("sheetId");
return new Uri($"/xl/worksheets/sheet{sheetId}.xml", UriKind.Relative);
}
}
}
return null;
}
}
导入格式XLSX

上述代码可进一步改进报错信息
cs
try
{
using (FileStream stream = File.Open(openFileDialog1.FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
catch (IOException)
{
MessageBox.Show($"文件已被占用", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
界面展示:
