.Net操作Excel —— NPOI

摘要:
实际上,我们可以首先创建一个excel表,并在excel中操作单元格以满足我们的要求,然后使用NPOI读取并获取其DataFormat。

近期的两个项目都有关于NPOI的功能,经过了一点学习,自己也摸索了一会,感觉还有点意思。现在将部分代码分享一下。一部分是C#代码,一部分是VB.Net的,懒得修改了,基本上都是从项目文件中copy出来的。如果错漏,请指教。

概述:

1、整个Excel表格:WorkBook(工作薄),包含的叫页(工作表):Sheet;行:Row;单元格Cell。

2、NPOI是POI的C#版本,NPOI的行和列的index都是从0开始

3、POI读取Excel有两种格式一个是HSSF,另一个是XSSF。 HSSF和XSSF的区别如下: 
HSSF is the POI Project's pure Java implementation of the Excel '97(-2007) file format. 
XSSF is the POI Project's pure Java implementation of the Excel 2007 OOXML (.xlsx) file format. 
即:HSSF适用2007以前的版本,XSSF适用2007版本及其以上的。

4、NPOI能够在没有安装微软Office的情况下读写Office文件,支持的文件格式包括xls, doc, ppt等。

引用:

Manage NuGet packages -> NPOI

.Net操作Excel —— NPOI第1张

读取excel:

       1、Asp.Net使用FileUpload控件上传excel文件(VB.Net代码):

Dim fileOriginalPath As String = excelUploader.PostedFile.FileName
Dim fileName As String = excelUploader.FileName
Dim extension = Path.GetExtension(fileOriginalPath).ToLower()

Dim workbook As IWorkbook
If (extension = ".xlsx") Then   'excel 2007
     workbook = New XSSFWorkbook(excelUploader.PostedFile.InputStream)
Else                                  'excel 2003
     workbook = New HSSFWorkbook(excelUploader.PostedFile.InputStream)
End If

  2、WPF读取本地excel文件:

using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))  
{  
            hssfworkbook = new HSSFWorkbook(file);  
}  

//其实HSSFWorkbook/XSSFWorkbook的构造方法可以直接传入FileInfo做参数

  3、WPF读取嵌入在资源文件的excel表格

        public XSSFWorkbook ReadDemoExcel()
        {
            MemoryStream ms = new MemoryStream(Properties.Resources.QNetTimesheet);
            ms.Position = 0;

            XSSFWorkbook book = new XSSFWorkbook(ms);
            return book;
        }

获取表(sheet)、行(row)、单元格(cell):

ISheet sheet = book.GetSheetAt(0)  //除了根据index,还可以根据名字获取:book.GetSheet("da")

IRow row = sheet.GetRow(0);

ICell cell = row.GetCell(4);  //row.Cells(i)方法也可以获取单元格, 但是此方法会跳过null的单元格。譬如,如果cell0跟cell3之间有一个单元格是null,那么row.Cells(3)就不会是你想要的那个cell...Please use row.GetCell(i)!!!!!

book.SetSheetName(1, "新名字");//修改sheet名字

IRow newRow = sheet.CreateRow(i);//创建新行

 int rowIndex = sheet.LastRowNum;//最后一行的index

单元格的相关操作:

ICell dateCell = row.CreateCell(0);
dateCell.SetCellValue(cardInfoList[i].Date);

ICell dayCell = row.CreateCell(1);
dayCell.CellFormula = string.Format("WEEKDAY(A{0})", row.RowNum + 1);//设置公式, 并不需要“=”号

ICell totalHoursCell = row.CreateCell(6);
totalHoursCell.CellFormula = string.Format("SUM(G{0}:G{1})", x, y);//设置公式

设置单元格样式(CellStyle):

private ICellStyle GetCellDataStyle(IWorkbook book)
        {
            ICellStyle cs = book.CreateCellStyle();
            cs.BorderBottom = BorderStyle.Thin;
            cs.BorderLeft = BorderStyle.Thin;
            cs.BorderRight = BorderStyle.Thin;
            cs.BorderTop = BorderStyle.Thin;

            cs.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.LightYellow.Index;//单元格背景色
            cs.FillPattern = FillPattern.SolidForeground;

            cs.DataFormat = 1;//在excel中可以Format Cells->Caregory->Custom设置Type使得单元格对数据显示不同的格式,比如可以设置显示成整形、金额、浮点数或者星期几等等等,可以看下面的“DataFormat”部分
            cs.Alignment = HorizontalAlignment.Center;//水平对齐

            return cs;
        }


cell.CellStyle = GetCellDataStyle(book);//赋值

单元格的DataFormat:

.Net操作Excel —— NPOI第2张.Net操作Excel —— NPOI第3张.Net操作Excel —— NPOI第4张

可以看到,对同一个单元格,设置不同的DataFormat,最终显示的内容是不同的。在NPOI中,我们可以通过对单元格设置其DataFormat属性来达到我们的目的。

此属性是int类型,网上的例子不齐全。现实中,我们可以先创建一个excel表并且在excel中操作单元格使得其达到我们的要求,然后用NPOI读取得知其DataFormat。

嗯,第一张截图显示Wednesday是我用公式=WEEKDAY(A7)根据日期计算并显示的,DataFormat是185

/*
                0, "General"
                1, "0"
                2, "0.00"
                3, "#,##0"
                4, "#,##0.00"
                5, "($#,##0_);($#,##0)"
                6, "($#,##0_);[Red]($#,##0)"
                7, "($#,##0.00);($#,##0.00)"
                8, "($#,##0.00_);[Red]($#,##0.00)"
                9, "0%"
                0xa, "0.00%"
                0xb, "0.00E+00"
                0xc, "# ?/?"
                0xd, "# ??/??"
                0xe, "m/d/yy"
                0xf, "d-mmm-yy"
                0x10, "d-mmm"
                0x11, "mmm-yy"
                0x12, "h:mm AM/PM"
                0x13, "h:mm:ss AM/PM"
                0x14, "h:mm"
                0x15, "h:mm:ss"
                0x16, "m/d/yy h:mm"
                // 0x17 - 0x24 reserved for international and undocumented 0x25, "(#,##0_);(#,##0)"
                0x26, "(#,##0_);[Red](#,##0)"
                0x27, "(#,##0.00_);(#,##0.00)"
                0x28, "(#,##0.00_);[Red](#,##0.00)"
                0x29, "_(*#,##0_);_(*(#,##0);_(* "-"_);_(@_)"
                0x2a, "_($*#,##0_);_($*(#,##0);_($* "-"_);_(@_)"
                0x2b, "_(*#,##0.00_);_(*(#,##0.00);_(*"-"??_);_(@_)"
                0x2c, "_($*#,##0.00_);_($*(#,##0.00);_($*"-"??_);_(@_)"
                0x2d, "mm:ss"
                0x2e, "[h]:mm:ss"
                0x2f, "mm:ss.0"
                0x30, "##0.0E+0"
                0x31, "@" - This is text format.
                0x31 "text" - Alias for "@" 
            */

将excel内容转换为DataTable(VB.Net代码):

    Private Function GetDataTableFromExcel(workbook As IWorkbook) As DataTable
        Dim sheet = workbook.GetSheetAt(0)
        Dim rows = sheet.GetRowEnumerator()
        Dim dt = New DataTable()
        Dim j As Int16

        Dim headerRow = sheet.GetRow(0)
        For j = 0 To headerRow.Cells.Count - 1 'headerRow.LastCellNum - 1
            Dim columnName As String = headerRow.Cells(j).ToString()
            If Not (j = headerRow.Cells.Count - 1 And String.IsNullOrEmpty(columnName)) Then
                dt.Columns.Add(columnName)
            End If
        Next

        rows.MoveNext()
        While rows.MoveNext()
            Dim row As IRow
            row = rows.Current
            Dim isRowEmpty As Boolean = IsEmptyRow(row)
            If isRowEmpty Then
                Continue While 'do not add empty row to data table
            End If

            Dim dr As DataRow
            dr = dt.NewRow()
            Dim i As Int16
            For i = 0 To dt.Columns.Count - 1
                Dim cell As ICell
                cell = row.GetCell(i) 'row.Cells(i), this method will ignore the null column automatically...Please use row.GetCell(i)!!!!!
                If cell Is Nothing Then
                    dr(i) = ""
                Else
                    Try
                        Select Case cell.CellType
                            Case CellType.Blank
                                dr(i) = ""
                            Case CellType.String
                                dr(i) = cell.StringCellValue
                            Case CellType.Numeric
                                If DateUtil.IsCellDateFormatted(cell) Then
                                    dr(i) = cell.DateCellValue
                                Else
                                    dr(i) = cell.NumericCellValue
                                End If
                            Case Else
                                dr(i) = cell.ToString()
                        End Select
                    Catch ex As Exception
                        dr(i) = ""
                    End Try
                End If
            Next
            dt.Rows.Add(dr)
        End While

        Return dt
    End Function

    Private Function IsEmptyRow(row As IRow) As Boolean
        Dim isEmpty As Boolean = True
        Dim i As Int16
        For i = 0 To row.Cells.Count - 1
            Dim cell As ICell
            cell = row.GetCell(i)
            If cell IsNot Nothing Then
                If cell.CellType <> CellType.Blank Then
                    isEmpty = False
                    Exit For
                End If
            End If
        Next
        Return isEmpty
    End Function

将NPOI生成的excel内容保存为文件:

  1、WPF程序将excel内容保存为本地文件:

XSSFWorkbook excelBook = npoiHelper.CreateExcel();
using (MemoryStream MS = new MemoryStream())
{
    excelBook.Write(MS);
    byte[] excelBytes = MS.ToArray();
    string excelPath = "C:Users	est.xlsx";
    using (FileStream fs = new FileStream(excelPath, FileMode.Create, FileAccess.Write))
    {
         fs.Write(excelBytes, 0, excelBytes.Length);
    }
}

  2、Asp.net服务器返回文件让用户保存(VB.Net代码):

Dim response As HttpResponse = HttpContext.Current.Response

response.Clear()
response.ClearHeaders()
response.ClearContent()
response.Charset = ""

response.ContentType = "application/vnd.ms-excel"
response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}.xls", HttpUtility.UrlEncode(title + "_" + DateTime.Now.ToString("yyyy-MM-dd HH-mm"), System.Text.Encoding.UTF8)))

Dim MS = New MemoryStream()
book.Write(MS)
response.BinaryWrite(MS.ToArray())
response.End()
response.Flush()
MS.Close()
MS.Dispose()

参考:

Class HSSFDataFormat

Net操作Excel(终极方法NPOI)

NPOI读写Excel

免责声明:文章转载自《.Net操作Excel —— NPOI》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇HBase 的安装与配置linux随笔:安装软连接时:ln: failed to create symbolic link ‘/usr/bin/python3/python3’: File exists下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

android http 和https请求

1 private static final int CONNECTION_TIMEOUT = 10000; 2 3 public static String doHttpGet(String serverURL) throws Exception { 4 HttpParams httpParameters...

【Word&amp;amp;Excel】【3】Excel替换某一行/列的内容

正文: 1,选中某一列,按组合键“ctrl+f”打开查找与替换对话框 2,输入要查找的内容,点击查找全部 3,在查找出来的内容中选中一行数据,按“ctrl+A”选中全部 4,在弹窗顶部,切换到替换,点击全部替换就可以了 参考博客: excel替换功能,只替换某一列/行的内容_百度经验https://jingyan.baidu.com/article/fcb...

WPF 导出EXCEL 方法

是用WPF将数据导出成EXCEL其实和其他.NET应用是相通的,ASP.NET也好WINFORM也好,都是用相同的方法实现,唯一不同的是ASP.NET中可能会存在用户权限的问题,毕竟ASP.NET的执行用户是IIS指定的用户而不是默认的系统用户。 具体实现方法如下,代码中使用完整的名称空间,便于理解 第一步,不许引用Excel的程序集,不同于网上其他文章,...

piap.excel 微软 时间戳转换mssql sql server文件时间戳转换unix 导入mysql

piap.excel 微软 时间戳转换mssql sql server文件时间戳转换unix 导入mysql 需要不个mssql的sql文件导入mysql.他们的时间戳格式不同..ms用的是自定义的时间戳 excel时间戳跟mssql的一样,ms系列的都是中个阿.. 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:att...

像Excel一样使用python进行数据分析(3)

像Excel一样使用python进行数据分析(1) 像Excel一样使用python进行数据分析(2) 7,数据汇总 第七部分是对数据进行分类汇总,Excel中使用分类汇总和数据透视可以按特定维度对数据进行汇总,python中使用的主要函数是groupby和pivot_table。下面分别介绍这两个函数的使用方法。 分类汇总 Excel的数据目录下提供了“...

使用QtXlsx来读写excel文件

概述:QtXlsx是功能非常强大和使用非常方便的操作excel类库。包括对excel数据读写、excel数据格式设置及在excel里面根据数据生成各种图表。 下面重点介绍如何安装和使用QtXlsx。 一、获取QtXlsx。 1、通过下面地址获取:https://github.com/dbzhang800/QtXlsxWriter 2、得到的是包括源码、各种...