当前位置:首页>Excel>C#中使用NPOI读取和写入Excel数据

C#中使用NPOI读取和写入Excel数据

  • 2026-08-13 11:41:20
C#中使用NPOI读取和写入Excel数据

本文介绍在C#代码中如何使用NPOI读取和写入Excel数据。

安装NPOI组件

首先,通过Visual Studio菜单“工具”>>NuGet包管理”>>“管理解决方案的NuGet程序包”,打开NuGet管理窗口;然后,在“浏览”页中搜索“npoi”,选中“NPOI”,并安装到当前项目中。如下图所示。

##安装NPOI组件

点击“安装”后接受一些协议,然后等待安装完成即可。

将数据写入Excel

下面的代码(cfx/office/tExcelWriter.cs)是tExcelWriter类的一部分,可复制到Visual Studio中阅读和测试。

C#

using System;

using System.IO;

using System.Data;

using NPOI.SS.UserModel;

using NPOI.HSSF.UserModel;

using NPOI.XSSF.UserModel;

namespace cfx.office

{

public class   tExcelWriter

{

private string   myFileName;

private DataTable   myData;

private string   mySheetName;

private int   myBeginRow;

private int   myBeginColumn;

private bool   myWriteColumnName;

//

private   tExcelWriter() { }

//

public static   tExcelWriter Create(string filename,

DataTable data,   string sheetName = null,

int beginRow =   1, int beginCol = 1,

bool   writeColumnName = true)

{

return new   tExcelWriter()

{

myFileName =   filename,

myData =   data,

mySheetName   = sheetName,

myBeginRow =   beginRow - 1,

myBeginColumn = beginCol - 1,

myWriteColumnName = writeColumnName

};

}

//

public bool Write()

{

string ext =   Path.GetExtension(myFileName).ToLower();

if (ext ==   ".xls") return WriteXls();

else return   WriteXlsx();

}

// DataTable对象数据写入.xls文件指定工作表的指定位置

private bool   WriteXls()

{

try

{

if (myData   == null || myData.Columns.Count < 1)

return   false;

//

using   (HSSFWorkbook wb = new HSSFWorkbook())

{

if   (mySheetName == null || mySheetName.Trim().Length == 0)

mySheetName = "数据";

ISheet   sheet = wb.CreateSheet(mySheetName);

// 写入工作表

int   curRow = myBeginRow;

// 写入列名

if   (myWriteColumnName)

{

IRow   sheetRow = sheet.CreateRow(curRow);

for   (int col = 0; col < myData.Columns.Count; col++)

{

ICell cell = sheetRow.CreateCell(col + myBeginColumn);

cell.SetCellType(CellType.String);

cell.SetCellValue(myData.Columns[col].ColumnName);

}

curRow++;

}

// 日期和时间格式

IDataFormat dataFormat = wb.CreateDataFormat();

ICellStyle datetimeStyle = wb.CreateCellStyle();

datetimeStyle.DataFormat =

dataFormat.GetFormat("yyyy/MM/dd HH:mm:ss");

// 写入数据行

for (int   row = 0; row < myData.Rows.Count; row++)

{

IRow   sheetRow = sheet.CreateRow(curRow++);

for   (int col = 0; col < myData.Columns.Count; col++)

{

ICell cell = sheetRow.CreateCell(col + myBeginColumn);

if (myData.Rows[row][col] == DBNull.Value)

{

cell.SetCellValue("");

}

else

{

Type dataType = myData.Columns[col].DataType;

if (Comm.IsNumeric(dataType))

{

cell.SetCellType(CellType.Numeric);

double result;

if (Obj.TryToDbl(myData.Rows[row][col], out result))

cell.SetCellValue(result);

}

else if (dataType.Name == "DateTime")

{

cell.CellStyle = datetimeStyle;

DateTime result;

if (Obj.TryToDate(myData.Rows[row][col], out result))

cell.SetCellValue(result);

}

else if (dataType.Name == "Boolean")

{

cell.SetCellType(CellType.Boolean);

cell.SetCellValue(Obj.ToBool(myData.Rows[row][col]));

}

else

{

cell.SetCellType(CellType.String);

cell.SetCellValue(Obj.ToStr(myData.Rows[row][col]));

}

}

}

}

//

using   (FileStream fs = new FileStream(myFileName,

FileMode.Create, FileAccess.Write))

{

wb.Write(fs);

}

return   true;

}

}

catch

{

return   false;

}

}

// DataTable对象数据写入.xlsx文件指定工作表的指定位置

private bool   WriteXlsx()

{

try

{

if (myData   == null || myData.Columns.Count < 1)

return   false;

//

using   (XSSFWorkbook wb = new XSSFWorkbook())

{

if   (mySheetName == null || mySheetName.Trim().Length == 0)

mySheetName = "数据";

ISheet   sheet = wb.CreateSheet(mySheetName);

// 写入工作表

int   curRow = myBeginRow;

// 写入列名

if   (myWriteColumnName)

{

IRow   sheetRow = sheet.CreateRow(curRow);

for   (int col = 0; col < myData.Columns.Count; col++)

{

ICell cell = sheetRow.CreateCell(col + myBeginColumn);

cell.SetCellType(CellType.String);

cell.SetCellValue(myData.Columns[col].ColumnName);

}

curRow++;

}

// 日期和时间格式

IDataFormat dataFormat = wb.CreateDataFormat();

ICellStyle datetimeStyle = wb.CreateCellStyle();

datetimeStyle.DataFormat =

dataFormat.GetFormat("yyyy/MM/dd HH:mm:ss");

// 写入数据行

for (int   row = 0; row < myData.Rows.Count; row++)

{

IRow   sheetRow = sheet.CreateRow(curRow++);

for   (int col = 0; col < myData.Columns.Count; col++)

{

ICell cell = sheetRow.CreateCell(col + myBeginColumn);

if (myData.Rows[row][col] == DBNull.Value)

{

cell.SetCellValue("");

}

else

{

Type dataType = myData.Columns[col].DataType;

if (Comm.IsNumeric(dataType))

{

cell.SetCellType(CellType.Numeric);

double result;

if (Obj.TryToDbl(myData.Rows[row][col], out result))

cell.SetCellValue(result);

}

else if (dataType.Name == "DateTime")

{

cell.CellStyle = datetimeStyle;

DateTime result;

if (Obj.TryToDate(myData.Rows[row][col], out result))

cell.SetCellValue(result);

}

else if (dataType.Name == "Boolean")

{

cell.SetCellType(CellType.Boolean);

cell.SetCellValue(Obj.ToBool(myData.Rows[row][col]));

}

else

{

cell.SetCellType(CellType.String);

cell.SetCellValue(Obj.ToStr(myData.Rows[row][col]));

}

}

}

}

//

using   (FileStream fs = new FileStream(myFileName,

FileMode.Create, FileAccess.Write))

{

wb.Write(fs);

}

return   true;

}

}

catch

{

return   false;

}

}

// 其它代码

}

}

tExcelWriter类中,首先定义了6个内部字段,分别保存写入Excel时需要的参数,包括:

  • myFileNamestring类型,写入的Excel文件路径。

  • myDataDataTable类型,包含写入数据的对象。

  • mySheetNamestring类型,写入的工作表(WorkSheet)名称。

  • myBeginRowint类型,在工作表中开始写入数据的行号。

  • myBeginColumnint类型,在工作表中开始写入数据的列号。

  • myWriteColumnNamebool类型,是否写入列名。

接下来是私有的构造函数,意味着不能在tExcelWriter类的外部使用new关键字创建实例,而创建实例的工作由Create()静态方法完成,方法中包含6个参数,对应了6个内部字段,分别是:

  • filename,指定写入的Excel路径。

  • data,指定写入数据的DataTable对象。

  • sheetName,写入的工作表名称,默认值为null。在不同的写入方法中处理会有所区别,稍后讨论。

  • beginRowbeginCol,指定开始写入数据的位置行号和列号,为更加直观设置数据,参数中使用从1开始的索引;但在Create()方法中会将指定的值减1,因为NPOI中的行号和列号是从0开始的。

  • writeColumnName,是否写入列名,默认为true

接下来定义了三个方法,分别是:

  • Write()方法,公共方法,其中会根据文件的扩展名分别调用WriteXls()WriteXlsx()方法。

  • WriteXls()方法,私有方法,将数据写入.xls文件。

  • WriteXlsx()方法,私有方法,将数据写入.xlsx文件。

WriteXls()方法和WriteXlsx()方法的代码几乎一样,只是在创建工作簿(Workbook)的时候使用了不同的类型,在处理.xls文件时使用了HSSFWorkbook类型,处理.xlsx文件时使用了XSSFWorkbook类型。这里,并没有将重复代码定义为单独的方法,在处理不同类型Excel文件时,如果对代码有特殊要求,调整起来会更加方便。

下面以WriteXls()方法为例进行说明。创建工作簿后,首先指定写入工作表的名称,如果指定的mySheetNamenull或空白字符串,则使用“数据”;然后,使用工作簿对象的CreateSheet()方法创建工作表(Worksheet)对象。

创建行对象(IRow类型)时,使用工作表对象的CreateRow()方法,其参数为从0开始的行索引(行号),即第一行索引为0、第二行索引1,以此类推。

创建单元格对象(ICell类型)时,使用行对象的CreateCell()方法,其参数为从0开始的列索引(列号)。

单元格对象的SetCellType()方法用于设置单元格类型,其参数使用CellType枚举,成员包括Numeric0)、String1)、Formula2)、Blank3)、Boolean4)、Error5)。

单元格对象的SetCellValue()方法可以设置单元格的值,方法有不同的重载版本,参数分别是stringdoubleboolDateTimeIRichTextString类型。

设置单元格格式时使用了IDataFormatICellStyle对象,方法中设置显示日期和时间数据格式为“年//日 时::秒”。

接下来会逐行写入数据,需要注意,单元格数据会根据DataTable对象中列的数据类型分别进行操作。

DBNull值时写入空白字符串。

数值类型时会转换为double类型写入。这里使用Obj.TryToDbl()方法转换,相关定义如下(cfx/Obj.cs):

C#

using System;

namespace cfx

{

public static class Obj

{

// 其它代码

//

public static string   ToStr(object obj, string defVal = "")

{

if (obj != null)

return   obj.ToString();

else

return   defVal;

}

//

public static bool   ToBool(object obj)

{

try { return   Convert.ToBoolean(obj); }

catch { return   false; }

}

// 尝试转换类型

public static bool   TryToDbl(object obj,out double result)

{

result = 0D;

return obj !=   null && double.TryParse(obj.ToString(), out result);

}

public static bool   TryToDate(object obj, out DateTime result)

{

result =   DateTime.MinValue;

return obj !=   null && DateTime.TryParse(obj.ToString(), out result);

}

}

}

DateTime类型数据会通过Obj.TryToDate()方法转换后写入,转换失败不写入单元格。

Boolean类型时通过Obj.ToBool()方法转换后写入。

其它类型则写入string类型数据。

保存工作簿时使用了Write()方法,其参数使用了FileStream对象,注意FileStream构造函数的使用,参数一指定了文件的路径,这里是需要保存Excel的文件路径;参数二指定打开模式,这里设置为创建(FileMode.Create),此操作会覆盖已存在的同名文件;参数二指定访问模式,这里指定FileAccess.Write,表示写入。

操作成功时,WriteXls()方法返回true,否则返回false

下面的代码,在Program.cs文件中测试tExcelWriter类的使用。

C#

using System;

using System.Data;

using cfx.office;

namespace csfx_demo

{

class Program

{

static void   Main(string[] args)

{

DataTable data =   tApp.DbJet.GetTable(@"select * from t1");

bool result =   tExcelWriter.Create(@"d:\t1.xls", data).Write();

Console.WriteLine(result);

}

}

}

代码会读取t1表中的所有数据,然后写入d:\t1.xls文件,操作成功会显示True。写入内容如下图所示。

##将数据导出到Excel文件

下面的代码(cfx/office/tExcelWriter.cs)定义了WriteExisted()和相关方法,用于将数据写入已存在的Excel文件。

C#

using System;

using System.IO;

using System.Data;

using NPOI.SS.UserModel;

using NPOI.HSSF.UserModel;

using NPOI.XSSF.UserModel;

namespace cfx.office

{

public class   tExcelWriter

{

// 其它代码

// 写入已存在的文件

public bool   WriteExisted()

{

string ext =   Path.GetExtension(myFileName).ToLower();

if (ext ==   ".xls") return WriteXlsExisted();

else return   WriteXlsxExisted();

}

// 写入已存在的xls文件

private bool   WriteXlsExisted()

{

try

{

if (myData   == null || myData.Columns.Count < 1 ||

File.Exists(myFileName) == false)

return   false;

//

using   (FileStream fs = new FileStream(myFileName,

FileMode.Open, FileAccess.Read))

{

using   (HSSFWorkbook wb = new HSSFWorkbook(fs))

{

int   sheetIndex = 0;

if   (mySheetName != null && mySheetName.Trim().Length > 0)

sheetIndex = wb.GetSheetIndex(mySheetName);

if   (sheetIndex == -1) sheetIndex = 0;

ISheet sheet = wb.GetSheetAt(sheetIndex);

//

int   curRow = myBeginRow;

// 写入列名

if   (myWriteColumnName)

{

IRow sheetRow = sheet.GetRow(curRow);

if (sheetRow == null) 

sheetRow = sheet.CreateRow(curRow);

for (int col = 0; col < myData.Columns.Count; col++)

{

int colIndex = col + myBeginColumn;

ICell cell = sheetRow.GetCell(colIndex);

if (cell == null) 

cell = sheetRow.CreateCell(colIndex);

cell.SetCellType(CellType.String);

cell.SetCellValue(myData.Columns[col].ColumnName);

}

curRow++;

}

// 日期和时间格式

IDataFormat dataFormat = wb.CreateDataFormat();

ICellStyle datetimeStyle = wb.CreateCellStyle();

datetimeStyle.DataFormat =

dataFormat.GetFormat("yyyy/MM/dd HH:mm:ss");

// 写入数据行

for   (int row = 0; row < myData.Rows.Count; row++)

{

IRow sheetRow = sheet.GetRow(curRow);

if (sheetRow == null)

sheetRow = sheet.CreateRow(curRow);

for (int col = 0; col < myData.Columns.Count; col++)

{

int colIndex = col + myBeginColumn;

ICell cell = sheetRow.GetCell(colIndex);

if (cell == null) 

cell = sheetRow.CreateCell(colIndex);

if (myData.Rows[row][col] == DBNull.Value)

{

cell.SetCellValue("");

}

else

{

Type dataType = myData.Columns[col].DataType;

if (Comm.IsNumeric(dataType))

{

cell.SetCellType(CellType.Numeric);

double result;

if   (Obj.TryToDbl(myData.Rows[row][col], out result))

cell.SetCellValue(result);

}

else if (dataType.Name == "DateTime")

{

cell.CellStyle = datetimeStyle;

DateTime result;

if   (Obj.TryToDate(myData.Rows[row][col], out result))

cell.SetCellValue(result);

}

else if (dataType.Name == "Boolean")

{

cell.SetCellType(CellType.Boolean);

cell.SetCellValue(Obj.ToBool(myData.Rows[row][col]));

}

else

{

cell.SetCellType(CellType.String);

cell.SetCellValue(Obj.ToStr(myData.Rows[row][col]));

}

}

}

curRow++;

}

//

using (FileStream fs1 =

new FileStream(myFileName, FileMode.Create, FileAccess.Write))

{

wb.Write(fs1);

}

}

return   true;

}

}

catch

{

return   false;

}

}

// 写入已存在的xls文件

private bool   WriteXlsxExisted()

{

try

{

if (myData   == null || myData.Columns.Count < 1 ||

File.Exists(myFileName) == false)

return   false;

//

using   (FileStream fs = new FileStream(myFileName,

FileMode.Open, FileAccess.Read))

{

using   (XSSFWorkbook wb = new XSSFWorkbook(fs))

{

int   sheetIndex = 0;

if   (mySheetName != null && mySheetName.Trim().Length > 0)

sheetIndex = wb.GetSheetIndex(mySheetName);

if   (sheetIndex == -1) sheetIndex = 0;

ISheet sheet = wb.GetSheetAt(sheetIndex);

//

int   curRow = myBeginRow;

// 写入列名

if   (myWriteColumnName)

{

IRow sheetRow = sheet.GetRow(curRow);

if (sheetRow == null)

sheetRow = sheet.CreateRow(curRow);

for (int col = 0; col < myData.Columns.Count; col++)

{

int colIndex = col + myBeginColumn;

ICell cell = sheetRow.GetCell(colIndex);

if (cell == null)

cell = sheetRow.CreateCell(colIndex);

cell.SetCellType(CellType.String);

cell.SetCellValue(myData.Columns[col].ColumnName);

}

curRow++;

}

// 日期和时间格式

IDataFormat dataFormat = wb.CreateDataFormat();

ICellStyle datetimeStyle = wb.CreateCellStyle();

datetimeStyle.DataFormat =

dataFormat.GetFormat("yyyy/MM/dd HH:mm:ss");

// 写入数据行

for   (int row = 0; row < myData.Rows.Count; row++)

{

IRow sheetRow = sheet.GetRow(curRow);

if (sheetRow == null)

sheetRow = sheet.CreateRow(curRow);

for (int col = 0; col < myData.Columns.Count; col++)

{

int colIndex = col + myBeginColumn;

ICell cell = sheetRow.GetCell(colIndex);

if (cell == null)

cell = sheetRow.CreateCell(colIndex);

if (myData.Rows[row][col] == DBNull.Value)

{

cell.SetCellValue("");

}

else

{

Type dataType = myData.Columns[col].DataType;

if (Comm.IsNumeric(dataType))

{

cell.SetCellType(CellType.Numeric);

double result;

if   (Obj.TryToDbl(myData.Rows[row][col], out result))

cell.SetCellValue(result);

}

else if (dataType.Name == "DateTime")

{

cell.CellStyle = datetimeStyle;

DateTime result;

if   (Obj.TryToDate(myData.Rows[row][col], out result))

cell.SetCellValue(result);

}

else if (dataType.Name == "Boolean")

{

cell.SetCellType(CellType.Boolean);

cell.SetCellValue(Obj.ToBool(myData.Rows[row][col]));

}

else

{

cell.SetCellType(CellType.String);

cell.SetCellValue(Obj.ToStr(myData.Rows[row][col]));

}

}

}

curRow++;

}

//

using (FileStream fs1 =

new FileStream(myFileName, FileMode.Create, FileAccess.Write))

{

wb.Write(fs1);

}

}

return   true;

}

}

catch

{

return   false;

}

}

}

}

需要将数据写入已存在的Excel文件时,创建工作簿对象的方式有所不同,在创建HSSFWorkbookXSSFWorkbook对象时,需要使用一个包含写入文件路径的FileStream对象作为构造方法的参数,设置模式为打开(FileMode.Open),访问方式为读取(FileAccess.Read)即可。

获取工作表对象时,如果指定的工作表名称(mySheetName)为null、空白字符串,或者名称不存在,则默认使用第一个工作表(索引0)。其中,工作簿对象的GetSheetIndex()方法会根据工作表名返回索引值,工作表不存在时返回-1

获取行对象(IRow类型)时,为避免覆盖工作表中已存在的内容,首先会使用工作表对象的GetRow()方法获取,如果行不存在返回null,此时再使用CreateRow()方法创建行。单元格对象(ICell类型)的处理也是这样,首先会使用行对象的GetCell()方法获取单元格对象,如果单元格对象不存在会返回null,此时使用CreateCell()方法创建新的单元格对象。

最后,在保存Excel文件时要注意,这里会创建一个新的FileStream对象,设置打开模式为创建(FileMode.Create),访问方式为写入(FileAccess.Write);然后调用工作簿对象的Write()方法覆盖写入目标文件即可。

接下来,可以在d:\t1.xls文件中创建一个新的工作表,命名为“数据1”,然后在Program.cs文件中修改代码如下。

C#

using System;

using System.Data;

using cfx.office;

namespace csfx_demo

{

class Program

{

static void   Main(string[] args)

{

DataTable data =   tApp.DbJet.GetTable(@"select * from t1");

bool result = 

tExcelWriter.Create(@"d:\t1.xls", data,"数据1").WriteExisted();

Console.WriteLine(result);

}

}

}

导出数据如下图所示。

##将数据导出到已存在的Excel文件

实际工作中,可能还会先定义Excel模板,每次导出数据会复制模板文件到一个新的文件,然后写入数据。下面的代码(cfx/office/tExcelWriter.cs),在tExcelWriter类中添加WriteByTemplate()方法,用于将数据导出到Excel模板文件。

C#

using System;

using System.IO;

using System.Data;

using NPOI.SS.UserModel;

using NPOI.HSSF.UserModel;

using NPOI.XSSF.UserModel;

namespace cfx.office

{

public class   tExcelWriter

{

// 其它代码

// 按模板写入,参数为模板文件路径

public bool   WriteByTemplate(string template)

{

try

{

if   (File.Exists(template) == false) 

return   false;

File.Copy(template, myFileName, true);

return   WriteExisted();

}

catch { return   false; }

}

//

}

}

WriteByTemplate()方法的参数需要指定模板文件的路径,方法中会根据文件扩展名分别调用WriteXlsExisted()WriteXlsxExisted()方法。

接下来,在d:盘下创建template.xlsx文件,并修改第一个工作表内容如下图所示。

##定义Excel模板

下面的代码,在Program.cs文件中测试按模板导出数据。

C#

using System;

using System.Data;

using cfx.office;

namespace csfx_demo

{

class Program

{

static void   Main(string[] args)

{

DataTable data =   tApp.DbJet.GetTable(@"select * from t1");

bool result =

tExcelWriter.Create(@"d:\t1.xlsx", data, null, 5, 3, false)

.WriteByTemplate(@"d:\template.xlsx");

Console.WriteLine(result);

}

}

}

执行代码,会复制d:\template.xlsx文件到d:\t1.xlsx,然后从第5行第3列开始写入数据,完成效果如下图所示。

##按模板写入Excel

读取Excel数据

接下来会实现读取Excel数据的功能,并将读取的数据保存到DataTable对象。下面的代码(cfx/office/tExcelReader.cs)创建tExcelReader类实现Excel数据读取功能。

C#

using System;

using System.Data;

using NPOI.SS.UserModel;

namespace cfx.office

{

public class   tExcelReader

{

// Excel文件名

private string   myFileName;

// 读取式作表索引

private int   mySheetIndex;

// 如果设置工作表名称,则优先使用

private string   mySheetName;

// 开始读取数据的行和列

private int   myBeginColumn;

private int   myBeginRow;

// 第一行作为列名

private bool   myFirstRowAsColumnName;

// 读取的行数,大于0时有效,否则读取全部

private int   myReadRowCount;

//

private   tExcelReader() { }

//

public static   tExcelReader Create(string filename,

int sheetIndex =   0, string sheetName = null,

int beginRow =   1, int beginCol = 1,

bool   firstRowAsColName = true, int readRowCount = -1)

{

return new   tExcelReader()

{

myFileName =   filename,

mySheetIndex   = sheetIndex,

mySheetName   = sheetName,

myBeginRow =   beginRow - 1,

myBeginColumn = beginCol - 1,

myFirstRowAsColumnName = firstRowAsColName,

myReadRowCount = readRowCount

};

}

// 执行读取操作

public DataTable   Read()

{

try

{

IWorkbook wb   = WorkbookFactory.Create(myFileName);

// 优先使用名称获取工作表

if   (mySheetName != null)

mySheetIndex = wb.GetSheetIndex(mySheetName);

if   (mySheetIndex < 0 || mySheetIndex > wb.NumberOfSheets - 1)

mySheetIndex = 0;

ISheet sheet   = wb.GetSheetAt(mySheetIndex);

// 读取第一行列数为全部行读取列数

int colCount   = sheet.GetRow(myBeginRow).LastCellNum;

int rowCount   = sheet.LastRowNum + 1;

// 读取数据并添加到DataTable对象

DataTable   tbl = new DataTable();

// 添加DataTable对象的列

for (int col   = myBeginColumn; col < colCount; col++)

tbl.Columns.Add();

// 

IRow   readRow;

// 读取行数据计数

int   readRowCounter = 0;

//

for (int row   = myBeginRow; row < rowCount; row++)

{

readRow   = sheet.GetRow(row);

DataRow   dataRow = tbl.NewRow();

for (int   col = myBeginColumn; col < colCount; col++)

{

int   tblColIndex = col - myBeginColumn;

try

{

ICell cell = readRow.GetCell(col);

if (cell == null)

{

dataRow[tblColIndex] = DBNull.Value;

}

else if (cell.CellType == CellType.Numeric)

{

// Excel中的日期时间值是Double类型

if (DateUtil.IsCellDateFormatted(cell))

dataRow[tblColIndex] = cell.DateCellValue;

else

dataRow[tblColIndex] = cell.NumericCellValue;

}

else if (cell.CellType == CellType.Boolean)

{

dataRow[tblColIndex] =

cell.BooleanCellValue ? 1 : 0;

}

else

{

// 其它格式以文本形式显示,纯空白字符设置为空值

string val = cell.StringCellValue.Trim();

if (val.Length == 0)

dataRow[tblColIndex] = DBNull.Value;

else

dataRow[tblColIndex] = val;

}

}

catch

{

dataRow[tblColIndex] = DBNull.Value;

}

}

tbl.Rows.Add(dataRow);

// 读取行

readRowCounter++;

if   (myReadRowCount > 0 && myReadRowCount == readRowCounter)

break;

}

// 数据第一行提升为标题,然后从数据行删除

if   (myFirstRowAsColumnName)

{

string   sName;

for (int   col = 0; col < tbl.Columns.Count; col++)

{

sName = tbl.Rows[0][col].ToString().Trim();

if   (sName != "")

tbl.Columns[col].ColumnName = sName;

}

tbl.Rows.RemoveAt(0);

}

//

return tbl;

}

catch

{

return null;

}

}

//

}

}

tExcelReader类中,首先定义了一些内部字段,用于保存读取Excel数据的参数;私有构造函数确定不能在tExcelReader类的外部使用new关键字创建实例;Create()静态方法用于创建tExcelReader实例,其参数与这些字段一一对应,方法的参数包括:

  • filenamestring类型,设置读取数据的Excel文件路径。

  • sheetIndexint类型,指定读取工作表的索引,默认为0,即读取第一个工作表。

  • sheetNamestring类型,默认为null。设置读取的工作表名称,如果设置了名称,则优先使用。

  • beginRowbeginColint类型,设置开始读取位置的行号和列号,使用从1开始的序号。方法中会减1,因为NPOI中的行和列索引是从0开始的。

  • firstRowAsColNamebool类型,默认为true。设置是否将第一行提升为表的列标题。

  • readRowCountint类型,设置从起始行开始读取的最大行数,默认为-1,表示读取全部行。

数据读取操作使用Read()方法完成。方法中,首先使用WorkbookFactory.Create()方法创建工作簿对象,参数为Excel文件路径;此方法会自动识别文件类型。

接下来,确定读取的工作表时会优先使用工作表名称,如果没有指定工作表名称则使用索引值,如果索引值小于0或大于等于工作表的数量则默认使用0,即读取第一个工作表。

方法中,使用读取的第一行的列数为全部行的读取列数,这里使用了行对象的LastCellNum属性,此属性为只读属性,返回行中的单元格数量(最大索引加1)。

获取工作表的行数时,使用工作表对象的LastRowNum属性加1,其中,LastRowNum属性会返回最大的行索引值。

读取单元格数据时会分别处理以下情况:

  • 当单元格对象为null时,会在DataTable中写入DBNull值。

  • 当单元格数据为数值时,首先使用DateUtil.IsCellDateFormatted(cell)方法判断是不是日期格式,当数据为日期格式时,使用DateCellValue属性获取日期数据;如果只是单纯的数值数据,则使用NumericCellValue属性获取数值数据。

  • 当单元格为布尔(Boolean)类型时需要注意,这里会将TRUE值转换为1FALSE值转换为0,然后写入DataTable对象。这么做的原因是,在很多应用场景下,读取的Excel数据可能需要导入数据库,而关系型数据库没有布尔类型,所以使用10分别表示truefalse值。

  • 当单元格为其它类型时,会使用StringCellValue属性获取文本数据,这里,如果数据为空字符串或纯空白字符,会在DataTable对象中写入DBNull值,否则写入删除开始和结束位置空白字符后的文本内容。

  • 最后,当单元格数据处理异常时,同样会在DataTable对象中写入DBNull值。

下面了解一些DataTable对象的动态操作。

首先,添加列时可以使用DataTable对象Columns集合中的Add()方法,方法可以使用指定的列名作为参数,不指定列名时,列名会自动使用Column1Column2、……。获取列对象(DataColumn)时,可以在Columns集合中使用从0开始的数值索引或列名索引,读取列名时可以使用DataColumn对象的ColumnName属性。

创建新行时,使用DataTable对象的NewRow()方法,方法会返回一个新的DataRow对象。此时,行对象中的数据单元会自动匹配表中列的设置。

行对象中,可以使用开始的数值索引或列名索引获取列对应的数据单元。

将行对象添加到DataTable对象时,使用Rows集合中的Add()方法。

Read()方法的最后,如果需要将第一行提升为列名,会将第一行数据设置为对应的列名,然后将第一行数据删除。删除行时使用了Rows集合中的RemoveAt()方法,参数为删除行的索引(从0开始)。这里应注意,如对应的数据为空字符串或纯空白字符,则不作为列名。

假设d:\t1.xls文件中有如下图所示的数据。

##准备读取的数据

下面的代码,在Program.cs文件中测试tExcelReader类的使用。

C#

using System;

using System.Data;

using cfx.office;

namespace csfx_demo

{

class Program

{

static void   Main(string[] args)

{

DataTable data =   tExcelReader.Create(@"d:\t1.xls").Read();

Console.WriteLine(data.Rows.Count);

Console.WriteLine(data.Columns.Count);

for(int col = 0;   col < data.Columns.Count; col++)

{

Console.WriteLine(data.Columns[col].ColumnName);

}

}

}

}

代码会读取d:\t1.xls文件中第一个工作表的数据,读取位置默认为第一行第一列。执行代码会显示读取完成后的数据行数、列数和列名,结果如下图所示。

##读取Excel数据

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-14 08:32:58 HTTP/2.0 GET : https://h.sjds.net/a/549134.html
  2. 运行时间 : 0.150086s [ 吞吐率:6.66req/s ] 内存消耗:4,542.19kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=dbdf36d3a0c2f04f8d89b120c4a4b2b2
  1. /yingpanguazai/ssd/ssd1/www/h.sjds.net/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/h.sjds.net/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/h.sjds.net/runtime/temp/ad153693ed39fba6d1bda2fe72512cde.php ( 12.06 KB )
  140. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000760s ] mysql:host=127.0.0.1;port=3306;dbname=h_sjds;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000785s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000314s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000282s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000493s ]
  6. SELECT * FROM `set` [ RunTime:0.000224s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000524s ]
  8. SELECT * FROM `article` WHERE `id` = 549134 LIMIT 1 [ RunTime:0.000715s ]
  9. UPDATE `article` SET `lasttime` = 1786667578 WHERE `id` = 549134 [ RunTime:0.005200s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 65 LIMIT 1 [ RunTime:0.000256s ]
  11. SELECT * FROM `article` WHERE `id` < 549134 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000481s ]
  12. SELECT * FROM `article` WHERE `id` > 549134 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000414s ]
  13. SELECT * FROM `article` WHERE `id` < 549134 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000803s ]
  14. SELECT * FROM `article` WHERE `id` < 549134 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000637s ]
  15. SELECT * FROM `article` WHERE `id` < 549134 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001169s ]
0.151642s