本文是VB语法,相信写C#的同学一样能看懂能试用
因微软自带操作Excel 受环境因素影响较大,所以把项目部分导出切换成NOPI导出
版本区分
这里说的版本是扩展名的区分,只此两种:xls、xlsx
- xls版的主要命名空间
MPOI.HSSF
- xlsx 版的主要命名空间
NPOI.XSSF
遇到问题可以从使用的命名空间或者类上面看看是否用的对
实例代码
用在实际项目中验证过,导出效率还是不错的
- 准备模板文件
'准备模板
Dim templateFileName As String = Application.StartupPath + "\xls\季度财报.xlsx" '模板文件
Dim exportFileName As String = Application.StartupPath + "\Excel\季度财报.xlsx" '目的文件
'文件COPY
If System.IO.File.Exists(exportFileName) Then
System.IO.File.Copy(templateFileName, exportFileName, True)
Else
System.IO.File.Copy(templateFileName, exportFileName)
End If
System.IO.File.SetAttributes(exportFileName, IO.FileAttributes.Normal) '目的文件属性修改
Dim fs As FileStream = New FileStream(templateFileName, FileMode.Open, FileAccess.Read) '打开一个现有的Excel
最后一行是打开这个excel为后面写数据做准备
- 创建工作薄
Dim workbook As XSSFWorkbook = New XSSFWorkbook(fs)
Dim sheet As XSSFSheet = workbook.GetSheet("Sheet1")
- 生成模板行
正常模板只提供几行的模板行,实际数据可能远远超过这个行数,这就需要插入相同样式的行,保持模板表格的一致性
1.生成模板行需要考虑表头占的行数
2.NPOI的行索引是从0开始的
'生成模板行
' ds 是要导出的数据集
If ds.Tables(0).Rows.Count > 0 Then
For i As Integer = 0 To ds.Tables(0).Rows.Count - 1
'NPOI的移动行,移动行就等于插入了一个新行,一次移动一行,相当于插入一行无样式空白行,0和1 已经被表头占用
sheet.ShiftRows(2, sheet.LastRowNum, 1, True, False)
'因为在2除移动行,默认向下移动,所以2处是新行,获取此行准备设置样式
Dim rowInsert As IRow = sheet.CreateRow(2)
'获取有模板样式的行
'这里可以用sheet.GetRow(3) ,就算插入很多行,在下面也设置过样式的,理论上是可用的
'sheet.GetRow(3 + i) 是原妈模板中的行
Dim rowSource As IRow = sheet.GetRow(3 + i)
'设置新行的行样式
rowInsert.RowStyle = rowSource.RowStyle
'设置新行的行高
rowInsert.Height = rowSource.Height
'设置新行的所有单元格样式
For col As Integer = 0 To rowSource.LastCellNum
'获取有样式行 相同y轴的单元格
Dim cellsource As ICell = rowSource.GetCell(col)
'如果此单元格无效,则跳过此单元格的样式设置
If cellsource Is Nothing Then
Continue For
End If
'新行创建 相同y轴的单元格
Dim cellInsert As ICell = rowInsert.CreateCell(col)
'设置新行相同y轴单元格的样式
cellInsert.CellStyle = cellsource.CellStyle
Next
Next
End If
- 填充数据
'循环数据
For m As Integer = 0 To ds.Tables(0).Rows.Count - 1
row = sheet.GetRow(2+ m)'获取行 0 1 被 表头占用
'以下是设置对应单元格的值
row.GetCell(0).SetCellValue(ds.Tables(0).Rows(m).Item("PART_NAME").ToString())
row.GetCell(1).SetCellValue(ds.Tables(0).Rows(m).Item("TYPE_NAME").ToString())
row.GetCell(2).SetCellValue(ds.Tables(0).Rows(m).Item("UNIT_NAME").ToString())
row.GetCell(3).SetCellValue(ds.Tables(0).Rows(m).Item("MONTH_QTY").ToString())
row.GetCell(4).SetCellValue(ds.Tables(0).Rows(m).Item("PRICE_AVG").ToString())
row.GetCell(5).SetCellValue(ds.Tables(0).Rows(m).Item("AMOUNT_SUM").ToString())
row.GetCell(6).SetCellValue(ds.Tables(0).Rows(m).Item("IN_QTY").ToString())
row.GetCell(7).SetCellValue(ds.Tables(0).Rows(m).Item("IN_PRICE_AVG").ToString())
row.GetCell(8).SetCellValue(ds.Tables(0).Rows(m).Item("IN_AMOUNT_SUM").ToString())
row.GetCell(9).SetCellValue(ds.Tables(0).Rows(m).Item("OUT_QTY").ToString())
row.GetCell(10).SetCellValue(ds.Tables(0).Rows(m).Item("OUT_PRICE_AVG").ToString())
row.GetCell(11).SetCellValue(ds.Tables(0).Rows(m).Item("OUT_AMOUNT_SUM").ToString())
row.GetCell(12).SetCellValue(ds.Tables(0).Rows(m).Item("LAST_QTY").ToString())
row.GetCell(13).SetCellValue(ds.Tables(0).Rows(m).Item("LAST_PRICE_AVG").ToString())
row.GetCell(14).SetCellValue(ds.Tables(0).Rows(m).Item("LAST_AMOUNT_SUM").ToString())
Next
写入到文件
Dim fs1 = New FileStream(exportFileName, FileMode.Create) '另存一个Excel档
workbook.Write(fs1) '把book存到文件中释放对象
fs.Close() '释放对象
fs1.Close() '释放对象
sheet = Nothing '释放对象
workbook = Nothing '释放对象
完结
做一个完整的模板导出业务后,对NPOI的基本了解足够应对日常工作了