用NPOI将DataGridView中需要的列导出为Excel

NPOI是什么?
    NPOI是POI的.Net版本,即“N”表示“Net”。不论是NPOI还是POI,它们其实都是已经编写好的类库。类库大家并不陌生,我们在建立BLL层,DAL层,Facade层……,是不是都是在创建一个个类库啊。那么这个东西和它们差不多。
NPOI干什么的?
    提供对Microsoft Office格式的文档读和写的功能。也就是说不仅仅用于对Excel的读和写,还有Word,Power Point等。
为什么要用NPOI
    大家可以自己查查NPOI的优势,我自己能亲身感受到的一点是:在做第一遍机房收费系统(VB版)时,我们要导出Excel,引用Microsoft Excel Object Library,并且应用Excel.Workbook,Excel.Sheet对象完成导出功能。可是当电脑上没有安装Microsoft Office Excel时,是无法成功导出的。
NPOI实践
    首先从网上下载NPOI.dll。就像我在前面提到的NPOI是类库,所以会生成.dll文件,就像DAL.dll。
    这里以在机房收费系统重构版的实践应用为例。
    在U层添加引用,添加NPOI.dll文件。或直接将文件放到U层的bin\Debug文件夹下。
    接下来,就是代码部分。
    不过,我这里我先说一下我的需求:
如果DataGridView中有记录,则导出为Excel。
因为DataGridView中有的列我设置为隐藏(不可见),但是导出为Excel时,会把这些隐藏的列都给导出,如何设置使隐藏的列不被导出。
为了实现导出Excel的功能的复用,要将它封装到类里面。
    如图所示:

     一般用户查询余额窗体,它不需要看到“结账状态”一列,所以我将这列的Visible属性设为False:
     但是导出为Excel后,会将结账状态一列显示出来,或是显示为空的列,如图:


    需求和问题清楚了,下面请看我的实现:
    具体流程:
    当单击导出为Excel按钮时,会弹出保存对话框,输入文件名,选择保存路径,则会把数据存到Excel表中。
[vb] view plain copy 在CODE上查看代码片派生到我的代码片
Imports NPOI.HSSF.UserModel 'HSSF是Microsoft Excel 97-2003 格式读写库  
Imports NPOI.SS.UserModel   'Excel公用接口及Excel公式计算引擎  
Imports System.IO           '提供允许读写文件和数据流的类  
Public Class ExportExcel  
    ''' <summary>  
    ''' 导出为Excel  
    ''' </summary>  
    ''' <param name="dgv"></param>参数为DataGridView  
    ''' <remarks></remarks>  
    Public Shared Sub ExportExcel(ByVal dgv As System.Windows.Forms.DataGridView)  
        Dim workbook As New HSSFWorkbook    '工作簿  
        Dim sheet As HSSFSheet              '工作表  
        Dim excelrow As HSSFRow             '行集  
  
        Dim i As Integer                    '列的循环变量  
        Dim m As Integer                    '行的循环变量  
        Dim n As Integer                    '列的循环变量  
  
        Dim saveDialog As Windows.Forms.SaveFileDialog     '保存文件的对话框  
  
        Dim ms As MemoryStream                             '内存中的数据流  
        Dim fs As FileStream                               '文件流  
        Dim filename As String                             '保存时的文件名称  
  
        '如果DataGridView中没有数据,则不导出Excel  
        If dgv.Rows.Count = 0 Then  
            MsgBox("无法导出为Excel!", MsgBoxStyle.Exclamation, "温馨提示")  
            Return  
        End If  
  
        sheet = workbook.CreateSheet                      '在工作簿中创建表  
        excelrow = sheet.CreateRow(0)                     '在工作表中创建标题行Row(0)  
  
        '添加每列列标题  
        For i = 0 To dgv.Columns.Count - 1  
            '将可见的列的标题写到单元格中(如果某列不可见,那么会在导出的Excel中空出这列)  
            If dgv.Columns(i).Visible = True Then  
                excelrow.CreateCell(i).SetCellValue(dgv.Columns(i).HeaderText)  
            End If  
        Next  
        '添加其他行和列  
        For m = 1 To dgv.Rows.Count  
            excelrow = sheet.CreateRow(m)                  '每遍历一行,则在sheet中创建一行  
            For n = 0 To dgv.Columns.Count - 1             '遍历每一行中的所有列  
                '如果该列可见,则导出该列单元格的值  
                If dgv.Columns(n).Visible = True Then  
                    excelrow.CreateCell(n).SetCellValue(dgv.Rows(m - 1).Cells(n).Value.ToString)  
                End If  
                '如果该列不可见,则将该列设置为隐藏  
                If dgv.Columns(n).Visible = False Then  
                    sheet.SetColumnHidden(n, True)  
                End If  
            Next  
        Next  
  
  
  
        saveDialog = New Windows.Forms.SaveFileDialog                '保存文件对话框  
        saveDialog.DefaultExt = "xls"                                '设置默认文件扩展名  
        saveDialog.Filter = "Excel文件|*.xls"                        '文件类型  
        saveDialog.ShowDialog()                                      '弹出保存文件对话框  
  
        filename = saveDialog.FileName                               '将对话框中输入的文件名赋给filename  
        ms = New MemoryStream()  
        fs = New FileStream(filename, FileMode.Create)  
        workbook.Write(ms)                                           '写入数据   
        workbook.Write(fs)  
        fs.Close()                                                   '关闭文件  
        workbook = Nothing  
        ms.Close()  
        ms.Dispose()  
    End Sub  
  
End Class  


     调用:
[vb] view plain copy 在CODE上查看代码片派生到我的代码片
''' <summary>  
    ''' 导出为Excel  
    ''' </summary>  
    ''' <param name="sender"></param>  
    ''' <param name="e"></param>  
    ''' <remarks></remarks>  
    Private Sub btnExportExcel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExportExcel.Click  
        '当DataGridView中有记录时  
        If dtgrdRecord.Columns.Count <> 0 Then  
            '设置不可见的列  
            dtgrdRecord.Columns(4).Visible = False  
        End If  
        ExportExcel.ExportExcel(dtgrdRecord)  
    End Sub  

     效果:

    说明:SetColumnHidden可以设置某一列隐藏,这样在打开Excel时,我们不会看到隐藏的列,这样用户看起来比较舒服,当然如果你在Excel中将隐藏的列,设置为取消隐藏,则仍会显示列。以上代码可以实现不把某不可见的列中的值导出到Excel,并且将此列隐藏。

  

posted @ 2016-09-04 11:07  xszjk  阅读(503)  评论(0)    收藏  举报