NPOI使用手冊(cè)2

轉(zhuǎn)自鏈接

2.3.5 IF函數(shù)

2.3.6 CountIf和SumIf函數(shù)

2.3.7 Lookup函數(shù)

2.3.8隨機(jī)數(shù)函數(shù)

2.3.9通過NPOI獲得公式的返回值

2.4創(chuàng)建圖形

2.4.1畫線

2.4.2畫矩形

2.4.3畫圓形

2.4.4畫Grid

2.4.5插入圖片

2.5打印相關(guān)設(shè)置

2.6

高級(jí)功能

2.6.1調(diào)整表單顯示比例

2.6.2設(shè)置密碼

2.6.3組合行、列

2.6.4鎖定列

2.6.5顯示/隱藏網(wǎng)格線

2.6.6設(shè)置初始視圖的行、列

2.6.7數(shù)據(jù)有效性

2.6.8生成下拉式菜單

2.3.5用NPOI操作EXCEL--If函數(shù)

在Excel中,IF(logical_test,value_if_true,value_if_false)用來用作邏輯判斷。其中Logical_test表示計(jì)算結(jié)果為TRUE或FALSE的任意值或表達(dá)式; value_if_true表示當(dāng)表達(dá)式Logical_test的值為TRUE時(shí)的返回值;value_if_false表示當(dāng)表達(dá)式Logical_test的值為FALSE時(shí)的返回值。同樣在NPOI中也可以利用這個(gè)表達(dá)式進(jìn)行各種邏輯運(yùn)算。如下代碼分別設(shè)置了B2和D2單元格的用于邏輯判斷的公式。

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

HSSFRow?row1?=?sheet1.CreateRow(

0);

row1.CreateCell(

0).SetCellValue("姓名");

row1.CreateCell(

1).SetCellValue("身份證號(hào)");

row1.CreateCell(

2).SetCellValue("性別");

row1.CreateCell(

3).SetCellValue("語文");

row1.CreateCell(

4).SetCellValue("是否合格");

HSSFRow?row2?=?sheet1.CreateRow(

1);

row2.CreateCell(

0).SetCellValue("令狐沖");

row2.CreateCell(

1).SetCellValue("420821198808101014");

row2.CreateCell(

2).SetCellFormula("IF(MOD(MID(B2,18,1),2)=0,\"男\(zhòng)",\"女\")");

row2.CreateCell(

3).SetCellValue(85);

row2.CreateCell(

4).SetCellFormula("IF(D2>60,IF(D2>90,\"優(yōu)秀\",\"合格\"),\"不合格\")");

其中最關(guān)鍵的兩句執(zhí)行結(jié)果如下:

row2.CreateCell(2).SetCellFormula("IF(MOD(MID(B2,18,1),2)=0,\"男\(zhòng)",\"女\")");

row2.CreateCell(4).SetCellFormula("IF(D2>60,IF(D2>90,\"優(yōu)秀\",\"合格\"),\"不合格\")");

下面分別對(duì)這幾個(gè)函數(shù)作一些說明:

MOD(MID(B2,18,1),2)

:我們知道18位身份證號(hào)的第18位表示性別,偶數(shù)為男性,奇數(shù)為女性,所以用了MID(B2,18,1)取第18位數(shù)字(與C#中一般從0計(jì)數(shù)不同,第二個(gè)參數(shù)是從1算起,有關(guān)MID函數(shù)的更多信息,請(qǐng)參見字符串函數(shù)),用MOD取余函數(shù)判斷奇偶。在Excel中對(duì)數(shù)據(jù)類型的控制沒有C#中那么嚴(yán)格,如此例中我截取出來的是字符串,但當(dāng)我做取余運(yùn)算時(shí)Excel會(huì)自動(dòng)轉(zhuǎn)換。

IF(D2>60,IF(D2>90,"

優(yōu)秀","合格"),"不合格"):這是IF的嵌套使用,表示90分以上為優(yōu)秀,60分以上為合格,否則為不合格。

2.3.6用NPOI操作EXCEL--COUNTIF和SUMIF函數(shù)

一、COUNTIF這一節(jié),我們一起來學(xué)習(xí)Excel中另一個(gè)常用的函數(shù)--COUNTIF函數(shù),看函數(shù)名就知道這是一個(gè)用來在做滿足某條件的計(jì)數(shù)的函數(shù)。先來看一看它的語法:COUNTIF(range,criteria),參數(shù)說明如下:

Range需要進(jìn)行讀數(shù)的計(jì)數(shù)

Criteria條件表達(dá)式,只有當(dāng)滿足此條件時(shí)才進(jìn)行計(jì)數(shù)

接下來看一個(gè)例子,代碼如下:

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

HSSFRow?row1?=?sheet1.CreateRow(

0);

row1.CreateCell(

0).SetCellValue("姓名");

row1.CreateCell(

1).SetCellValue("成績(jī)");

HSSFRow?row2?=?sheet1.CreateRow(

1);

row2.CreateCell(

0).SetCellValue("令狐沖");

row2.CreateCell(

1).SetCellValue(85);

HSSFRow?row3?=?sheet1.CreateRow(

2);

row3.CreateCell(

0).SetCellValue("任盈盈");

row3.CreateCell(

1).SetCellValue(90);

HSSFRow?row4?=?sheet1.CreateRow(

3);

row4.CreateCell(

0).SetCellValue("任我行");

row4.CreateCell(

1).SetCellValue(70);

HSSFRow?row5?=?sheet1.CreateRow(

4);

row5.CreateCell(

0).SetCellValue("左冷嬋");

row5.CreateCell(

1).SetCellValue(45);

HSSFRow?row6?=?sheet1.CreateRow(

5);

row6.CreateCell(

0).SetCellValue("岳不群");

row6.CreateCell(

1).SetCellValue(50);

HSSFRow?row7?=?sheet1.CreateRow(

6);

row7.CreateCell(

0).SetCellValue("合格人數(shù):");

row7.CreateCell(

1).SetCellFormula("COUNTIF(B2:B6,\">60\")");

執(zhí)行結(jié)果如下:

我們可以看到,CountIf函數(shù)成功的統(tǒng)計(jì)出了區(qū)域“B2:B6”中成績(jī)合格的人數(shù)(這里定義成績(jī)大于60為合格)。

二、SUMIF

接下來,順便談?wù)劻硪粋€(gè)與CountIF類似的函數(shù)—SumIf函數(shù)。此函數(shù)用于統(tǒng)計(jì)某區(qū)域內(nèi)滿足某條件的值的求和(CountIf是計(jì)數(shù))。與CountIF不同,SumIF有三個(gè)參數(shù),語法為SumIF(criteria_range, criteria,sum_range),各參數(shù)的說明如下:

criteria_range條件測(cè)試區(qū)域,第二個(gè)參數(shù)Criteria中的條件將與此區(qū)域中的值進(jìn)行比較

criteria條件測(cè)試值,滿足條件的對(duì)應(yīng)的sum_range項(xiàng)將進(jìn)行求和計(jì)算

sum_range匯總數(shù)據(jù)所在區(qū)域,求和時(shí)會(huì)排除掉不滿足Criteria條件的對(duì)應(yīng)的項(xiàng)

我們還是以例子來加以說明:

Code

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet(

"Sheet1");

HSSFRow?row1?=?sheet1.CreateRow(

0);

row1.CreateCell(

0).SetCellValue("姓名");

row1.CreateCell(

1).SetCellValue("月份");

row1.CreateCell(

2).SetCellValue("銷售額");

HSSFRow?row2?=?sheet1.CreateRow(

1);

row2.CreateCell(

0).SetCellValue("令狐沖");

row2.CreateCell(

1).SetCellValue("一月");

row2.CreateCell(

2).SetCellValue(1000);

HSSFRow?row3?=?sheet1.CreateRow(

2);

row3.CreateCell(

0).SetCellValue("任盈盈");

row3.CreateCell(

1).SetCellValue("一月");

row3.CreateCell(

2).SetCellValue(900);

HSSFRow?row4?=?sheet1.CreateRow(

3);

row4.CreateCell(

0).SetCellValue("令狐沖");

row4.CreateCell(

1).SetCellValue("二月");

row4.CreateCell(

2).SetCellValue(2000);

HSSFRow?row5?=?sheet1.CreateRow(

4);

row5.CreateCell(

0).SetCellValue("任盈盈");

row5.CreateCell(

1).SetCellValue("二月");

row5.CreateCell(

2).SetCellValue(1000);

HSSFRow?row6?=?sheet1.CreateRow(

5);

row6.CreateCell(

0).SetCellValue("令狐沖");

row6.CreateCell(

1).SetCellValue("三月");

row6.CreateCell(

2).SetCellValue(3000);

HSSFRow?row7?=?sheet1.CreateRow(

6);

row7.CreateCell(

0).SetCellValue("任盈盈");

row7.CreateCell(

1).SetCellValue("三月");

row7.CreateCell(

2).SetCellValue(1200);

HSSFRow?row8?=?sheet1.CreateRow(

7);

row8.CreateCell(

0).SetCellValue("令狐沖一季度銷售額:");

row8.CreateCell(

2).SetCellFormula("SUMIF(A2:A7,\"=令狐沖\",C2:C7)");

HSSFRow?row9?=?sheet1.CreateRow(

8);

row9.CreateCell(

0).SetCellValue("任盈盈一季度銷售額:");

row9.CreateCell(

2).SetCellFormula("SUMIF(A2:A7,\"=任盈盈\",C2:C7)");

執(zhí)行結(jié)果如下:

如上圖,SUMIF統(tǒng)計(jì)出了不同人一季度的銷售額。

2.3.7用NPOI操作EXCEL--LOOKUP函數(shù)

今天,我們一起學(xué)習(xí)Excel中的查詢函數(shù)--LOOKUP。其基本語法形式為L(zhǎng)OOKUP(lookup_value,lookup_vector,result_vector)。還是以例子加以說明更容易理解:

Code

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet(

"Sheet1");

HSSFRow?row1?=?sheet1.CreateRow(

0);

row1.CreateCell(

0).SetCellValue("收入最低");

row1.CreateCell(

1).SetCellValue("收入最高");

row1.CreateCell(

2).SetCellValue("稅率");

HSSFRow?row2?=?sheet1.CreateRow(

1);

row2.CreateCell(

0).SetCellValue(0);

row2.CreateCell(

1).SetCellValue(3000);

row2.CreateCell(

2).SetCellValue(0.1);

HSSFRow?row3?=?sheet1.CreateRow(

2);

row3.CreateCell(

0).SetCellValue(3001);

row3.CreateCell(

1).SetCellValue(10000);

row3.CreateCell(

2).SetCellValue(0.2);

HSSFRow?row4?=?sheet1.CreateRow(

3);

row4.CreateCell(

0).SetCellValue(10001);

row4.CreateCell(

1).SetCellValue(20000);

row4.CreateCell(

2).SetCellValue(0.3);

HSSFRow?row5?=?sheet1.CreateRow(

4);

row5.CreateCell(

0).SetCellValue(20001);

row5.CreateCell(

1).SetCellValue(50000);

row5.CreateCell(

2).SetCellValue(0.4);

HSSFRow?row6?=?sheet1.CreateRow(

5);

row6.CreateCell(

0).SetCellValue(50001);

row6.CreateCell(

2).SetCellValue(0.5);

HSSFRow?row8?=?sheet1.CreateRow(

7);

row8.CreateCell(

0).SetCellValue("收入");

row8.CreateCell(

1).SetCellValue("稅率");

HSSFRow?row9?=?sheet1.CreateRow(

8);

row9.CreateCell(

0).SetCellValue(7800);

row9.CreateCell(

1).SetCellFormula("LOOKUP(A9,$A$2:$A$6,$C$2:$C$6)");

這是一個(gè)根據(jù)工資查詢相應(yīng)稅率的例子。我們首先創(chuàng)建了不同工資區(qū)間對(duì)應(yīng)稅率的字典,然后根據(jù)具體的工資在字典中找出對(duì)應(yīng)的稅率。執(zhí)行后生成的Excel如下:

下面對(duì)各參數(shù)加以說明:第一個(gè)參數(shù):需要查找的內(nèi)容,本例中指向A9單元格,也就是7800;第二個(gè)參數(shù):比較對(duì)象區(qū)域,本例中的工資需要與$A$2:$A$6中的各單元格中的值進(jìn)行比較;第三個(gè)參數(shù):查找結(jié)果區(qū)域,如果匹配到會(huì)將此區(qū)域中對(duì)應(yīng)的數(shù)據(jù)返回。如本例中返回$C$2:$C$6中對(duì)應(yīng)的值??赡苡腥藭?huì)問,字典中沒有7800對(duì)應(yīng)的稅率啊,那么Excel中怎么匹配的呢?答案是模糊匹配,并且LOOKUP函數(shù)只支持模糊匹配。Excel會(huì)在$A$2:$A$6中找小于7800的最大值,也就是A3對(duì)應(yīng)的3001,然后將對(duì)應(yīng)的$C$2:$C$6區(qū)域中的C3中的值返回,這就是最終結(jié)果0.2的由來。這下明白了吧:)

VLOOKUP另外,LOOKUP函數(shù)還有一位大哥--VLOOKUP。兩兄弟有很多相似之處,但大哥本領(lǐng)更大。Vlookup用對(duì)比數(shù)與一個(gè)“表”進(jìn)行對(duì)比,而不是Lookup函數(shù)的某1列或1行,并且Vlookup可以選擇采用精確查詢或是模糊查詢方式,而Lookup只有模糊查詢。將上例中設(shè)置公式的代碼換成:

row9.CreateCell(1).SetCellFormula("VLOOKUP(A9,$A$2:$C$6,3,TRUE)");

執(zhí)行后生成的Excel樣式如下:

第一個(gè)參數(shù):需要查找的內(nèi)容,這里是A9單元格;第二個(gè)參數(shù):需要比較的表,這里是$A$2:$C$6,注意VLOOKUP匹配時(shí)只與表中的第一列進(jìn)行匹配。第三個(gè)參數(shù):匹配結(jié)果對(duì)應(yīng)的列序號(hào)。這里要對(duì)應(yīng)的是稅率列,所以為3。第四個(gè)參數(shù):指明是否模糊匹配。例子中的TRUE表示模糊匹配,與上例中一樣。匹配到的是第三行。如果將此參數(shù)改為FALSE,因?yàn)樵诒碇械牡?列中找不到7800,所以會(huì)報(bào)“#N/A”的計(jì)算錯(cuò)誤。

另外,還有與VLOKUP類似的HLOOKUP。不同的是VLOOKUP用于在表格或數(shù)值數(shù)組的首列查找指定的數(shù)值,并由此返回表格或數(shù)組當(dāng)前行中指定列處的數(shù)值。而HLOOKUP用于在表格或數(shù)值數(shù)組的首行查找指定的數(shù)值,并由此返回表格或數(shù)組當(dāng)前列中指定行處的數(shù)值。讀者可以自已去嘗試。

2.3.8用NPOI操作EXCEL--隨機(jī)數(shù)函數(shù)

我們知道,在大多數(shù)編程語言中都有隨機(jī)數(shù)函數(shù)。在Excel中,同樣存在著這樣一個(gè)函數(shù)—RAND()函數(shù),用于生成隨機(jī)數(shù)。先來看一個(gè)最簡(jiǎn)單的例子:

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

sheet1.CreateRow(

0).CreateCell(0).SetCellFormula("RAND()");

RAND()函數(shù)將返回一個(gè)0-1之間的隨機(jī)數(shù),執(zhí)行后生成的Excel文件如下:

這只是最簡(jiǎn)單直接的RAND()函數(shù)的應(yīng)用,只要我們稍加修改,就可以作出很多種變換。如取0-100之前的隨機(jī)整數(shù),可設(shè)置公式為:

sheet1.CreateRow(0).CreateCell(0).SetCellFormula("int(RAND()*100)");

取10-20之間的隨機(jī)實(shí)數(shù),可設(shè)置公式為:

sheet1.CreateRow(0).CreateCell(0).SetCellFormula("rand()*(20-10)+10");

隨機(jī)小寫字母:

sheet1.CreateRow(0).CreateCell(0).SetCellFormula("CHAR(INT(RAND()*26)+97)");

隨機(jī)大寫字母:

sheet1.CreateRow(0).CreateCell(0).SetCellFormula("CHAR(INT(RAND()*26)+65)")

隨機(jī)大小寫字母:

sheet1.CreateRow(0).CreateCell(0).SetCellFormula("CHAR(INT(RAND()*26)+if(INT(RAND()*2)=0,65,97))");

上面幾例中除了用到RAND函數(shù)以外,還用到了CHAR函數(shù)用來將ASCII碼換為字母,INT函數(shù)用來取整。值得注意的是INT函數(shù)不會(huì)四舍五入,無論小數(shù)點(diǎn)后是多少都會(huì)被舍去。這里只是RAND函數(shù)的幾個(gè)簡(jiǎn)單應(yīng)用,還有很多隨機(jī)數(shù)的例子都可以根據(jù)這些,再結(jié)合不同的其它函數(shù)引申出來。

2.3.9用NPOI操作EXCEL--通過NPOI獲得公式的返回值

前面我們學(xué)習(xí)了通過NPOI向Excel中設(shè)置公式,那么有些讀者可能會(huì)問:“NPOI能不能獲取公式的返回值呢?”,答案是可以!一、獲取模板文件中公式的返回值如在D盤中有一個(gè)名為text.xls的Excel文件,其內(nèi)容如下:

注意C1單元格中設(shè)置的是公式“$A1*$B1”,而不是值“12”。利用NPOI,只需要寫簡(jiǎn)單的幾句代碼就可以取得此公式的返回值:

HSSFWorkbook?wb?=newHSSFWorkbook(newFileStream("d:/test.xls",FileMode.Open));

HSSFCell?cell?=?wb.GetSheet(

"Sheet1").GetRow(0).GetCell(2);

System.Console.WriteLine(cell.NumericCellValue);

輸出結(jié)果為:

可見NPOI成功的“解析”了此.xls文件中的公式。注意NumericCellValue屬性會(huì)自動(dòng)根據(jù)單元格的類型處理,如果為空將返0,如果為數(shù)值將返回?cái)?shù)值,如果為公式將返回公式計(jì)算后的結(jié)果。單元格的類型可以通過CellType屬性獲取。

二、獲取NPOI生成的Excel文件中公式的返回值上例中是從一個(gè)已經(jīng)存在的Excel文件中獲取公式的返回值,那么如果Excel文件是通過NPOI創(chuàng)建的,直接用上面的方法獲取,可能得不到想要的結(jié)果。如:

1HSSFWorkbook?hssfworkbook?=newHSSFWorkbook();

2HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

3HSSFRow?row?=?sheet1.CreateRow(0);

4row.CreateCell(0).SetCellValue(3);

5row.CreateCell(1).SetCellValue(4);

6HSSFCell?cell?=?row.CreateCell(2);

78cell.SetCellFormula("$A1+$B1");

9System.Console.WriteLine(cell.NumericCellValue);

執(zhí)行上面代碼,將輸出結(jié)果“0”,而不是我們想要的結(jié)果“7”。那么將如何解決呢?這時(shí)要用到HSSFFormulaEvaluator類。在第8行后加上這兩句就可以了:

HSSFFormulaEvaluator?e?=newHSSFFormulaEvaluator(hssfworkbook);

cell?=?e.EvaluateInCell(cell);

運(yùn)行結(jié)果如下:

2.4.1用NPOI操作EXCEL--畫線

之所有說NPOI強(qiáng)大,是因?yàn)槌S玫腅xcel操作她都可以通過編程的方式完成。這節(jié)開始,我們開始學(xué)習(xí)NPOI的畫圖功能。先從最簡(jiǎn)單的開始,畫一條直線:

對(duì)應(yīng)的代碼為:

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

HSSFPatriarch?patriarch?=?sheet1.CreateDrawingPatriarch();

HSSFClientAnchor?a1?=

newHSSFClientAnchor(255,125,1023,150,0,0,2,2);

HSSFSimpleShape?line1?=?patriarch.CreateSimpleShape(a1);

line1.ShapeType?=?HSSFSimpleShape.OBJECT_TYPE_LINE;

line1.LineStyle?=?HSSFShape.LINESTYLE_SOLID;

//在NPOI中線的寬度12700表示1pt,所以這里是0.5pt粗的線條。line1.LineWidth?=6350;

通常,利用NPOI畫圖主要有以下幾個(gè)步驟:

1.

創(chuàng)建一個(gè)Patriarch;

2.

創(chuàng)建一個(gè)Anchor,以確定圖形的位置;

3.

調(diào)用Patriarch創(chuàng)建圖形;

4.

設(shè)置圖形類型(直線,矩形,圓形等)及樣式(顏色,粗細(xì)等)。

關(guān)于HSSFClientAnchor(dx1,dy1,dx2,dy2,col1,row1,col2,row2)的參數(shù),有必要在這里說明一下:

dx1

:起始單元格的x偏移量,如例子中的255表示直線起始位置距A1單元格左側(cè)的距離;

dy1

:起始單元格的y偏移量,如例子中的125表示直線起始位置距A1單元格上側(cè)的距離;

dx2

:終止單元格的x偏移量,如例子中的1023表示直線起始位置距C3單元格左側(cè)的距離;

dy2

:終止單元格的y偏移量,如例子中的150表示直線起始位置距C3單元格上側(cè)的距離;

col1

:起始單元格列序號(hào),從0開始計(jì)算;

row1

:起始單元格行序號(hào),從0開始計(jì)算,如例子中col1=0,row1=0就表示起始單元格為A1;

col2

:終止單元格列序號(hào),從0開始計(jì)算;

row2

:終止單元格行序號(hào),從0開始計(jì)算,如例子中col2=2,row2=2就表示起始單元格為C3;

最后,關(guān)于LineStyle屬性,有如下一些可選值,對(duì)應(yīng)的效果分別如圖所示:

2.4.2用NPOI操作EXCEL--畫矩形

上一節(jié)我們講了NPOI中畫圖的基本步驟:

1.

創(chuàng)建一個(gè)Patriarch;

2.

創(chuàng)建一個(gè)Anchor,以確定圖形的位置;

3.

調(diào)用Patriarch創(chuàng)建圖形;

4.

設(shè)置圖形類型(直線,矩形,圓形等)及樣式(顏色,粗細(xì)等)。

這一節(jié)我們將按照這個(gè)步驟創(chuàng)建一個(gè)矩形。廢話少說,上代碼:

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

HSSFPatriarch?patriarch?=?sheet1.CreateDrawingPatriarch();

HSSFClientAnchor?a1?=

newHSSFClientAnchor(255,125,1023,150,0,0,2,2);

HSSFSimpleShape?rec1?=?patriarch.CreateSimpleShape(a1);

//此處設(shè)置圖形類型為矩形rec1.ShapeType?=?HSSFSimpleShape.OBJECT_TYPE_RECTANGLE;

//設(shè)置填充色rec1.SetFillColor(125,125,125);

//設(shè)置邊框樣式rec1.LineStyle?=?HSSFShape.LINESTYLE_DASHGEL;

//設(shè)置邊框?qū)挾萺ec1.LineWidth?=25400;

//設(shè)置邊框顏色rec1.SetLineStyleColor(100,0,100);

代碼執(zhí)行效果:

其中SetFillColor和SetLineStyleColor函數(shù)的三個(gè)參數(shù)分別是RGB三色值,具體表示什么顏色,找個(gè)Photoshop試試:)關(guān)于HSSFClientAnchor參數(shù)說明、邊框樣式,邊框?qū)挾鹊恼f明可以參見前一篇博文:

http://www.cnblogs.com/atao/archive/2009/09/13/1565645.html

2.4.3用NPOI操作EXCEL--畫圓形

前面我們學(xué)習(xí)了NPOI中的畫簡(jiǎn)單直線和矩形的功能,今天我們一起學(xué)習(xí)一下它支持的另一種簡(jiǎn)單圖形--圓形。同樣,按照前面所講的繪圖“四步曲”:

1.

創(chuàng)建一個(gè)Patriarch;

2.

創(chuàng)建一個(gè)Anchor,以確定圖形的位置;

3.

調(diào)用Patriarch創(chuàng)建圖形;

4.

設(shè)置圖形類型(直線,矩形,圓形等)及樣式(顏色,粗細(xì)等)。還是以例子加以說明:

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

HSSFPatriarch?patriarch?=?sheet1.CreateDrawingPatriarch();

HSSFClientAnchor?a1?=

newHSSFClientAnchor(0,0,1023,0,0,0,1,3);

HSSFSimpleShape?rec1?=?patriarch.CreateSimpleShape(a1);

rec1.ShapeType?=?HSSFSimpleShape.OBJECT_TYPE_OVAL;

rec1.SetFillColor(

125,125,125);

rec1.LineStyle?=?HSSFShape.LINESTYLE_DASHGEL;

rec1.LineWidth?=

12700;

rec1.SetLineStyleColor(

100,0,100);

WriteToFile();

這里rec1.ShapeType =HSSFSimpleShape.OBJECT_TYPE_OVAL;表示圖形為橢圓。適當(dāng)調(diào)整HSSFClientAnchor的各參數(shù)可以得到圓形。關(guān)于HSSFClientAnchor構(gòu)造函數(shù)和邊框、填充色等前兩節(jié)都有介紹,這里不再重述。詳情情見:畫矩形畫線。

上面代碼執(zhí)行生成的Excel如下:

2.4.4用NPOI操作EXCEL--畫Grid

在NPOI中,本身沒有畫Grid的方法。但我們知道Grid其實(shí)就是由橫線和豎線構(gòu)成的,所在我們可以通過畫線的方式來模擬畫Grid。

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

HSSFRow?row?=?sheet1.CreateRow(

2);

row.CreateCell(

1);

row.HeightInPoints?=

240;

sheet1.SetColumnWidth(

2,9000);

intlinesCount?=20;

HSSFPatriarch?patriarch?=?sheet1.CreateDrawingPatriarch();

//因?yàn)镠SSFClientAnchor中dx只能在0-1023之間,dy只能在0-255之間,所以這里采用比例的方式doublexRatio?=1023.0/?(linesCount*10);

doubleyRatio?=255.0/?(linesCount*10);

//畫豎線intx1?=0;

inty1?=0;

intx2?=0;

inty2?=200;

for(inti?=0;?i?<?linesCount;?i++)

{

HSSFClientAnchor?a2?=

newHSSFClientAnchor();

a2.SetAnchor((

short)2,2,?(int)(x1?*?xRatio),?(int)(y1?*?yRatio),

(

short)2,2,?(int)(x2?*?xRatio),?(int)(y2?*?yRatio));

HSSFSimpleShape?shape2?=?patriarch.CreateSimpleShape(a2);

shape2.ShapeType?=?(HSSFSimpleShape.OBJECT_TYPE_LINE);

x1?+=

10;

x2?+=

10;

}

//畫橫線x1?=0;

y1?=

0;

x2?=

200;

y2?=

0;

for(inti?=0;?i?<?linesCount;?i++)

{

HSSFClientAnchor?a2?=

newHSSFClientAnchor();

a2.SetAnchor((

short)2,2,?(int)(x1?*?xRatio),?(int)(y1?*?yRatio),

(

short)2,2,?(int)(x2?*?xRatio),?(int)(y2?*?yRatio));

HSSFSimpleShape?shape2?=?patriarch.CreateSimpleShape(a2);

shape2.ShapeType?=?(HSSFSimpleShape.OBJECT_TYPE_LINE);

y1?+=

10;

y2?+=

10;

}

請(qǐng)注意HSSFClientAnchor對(duì)象中的dx只能取0-1023之間的數(shù),dy只能取0-255之間的數(shù)。我們可以理解為是將單元格的寬和高平分成了1023和255份,設(shè)置dx和dy時(shí)相當(dāng)于按比例取對(duì)應(yīng)的座標(biāo)。最終生成的Excel如下:

2.4.5用NPOI操作EXCEL--插入圖片

我們知道,在Excel中是可以插入圖片的。操作菜單是“插入->圖片”,然后選擇要插入圖片,可以很容易地在Excel插入圖片。同樣,在NPOI中,利用代碼也可以實(shí)現(xiàn)同樣的效果。在NPOI中插入圖片的方法與畫圖的方法有點(diǎn)類似:

//add?picture?data?to?this?workbook.

byte[]?bytes?=?System.IO.File.ReadAllBytes(@"D:\MyProject\NPOIDemo\ShapeImage\image1.jpg");

intpictureIdx?=?hssfworkbook.AddPicture(bytes,?HSSFWorkbook.PICTURE_TYPE_JPEG);

//create?sheet

HSSFSheet?sheet?=?hssfworkbook.CreateSheet("Sheet1");

//?Create?the?drawing?patriarch.??This?is?the?top?level?container?for?all?shapes.

HSSFPatriarch?patriarch?=?sheet.CreateDrawingPatriarch();

//add?a?picture

HSSFClientAnchor?anchor?=newHSSFClientAnchor(0,0,1023,0,0,0,1,3);

HSSFPicture?pict?=?patriarch.CreatePicture(anchor,?pictureIdx);

與畫簡(jiǎn)單圖形不同的是,首先要將圖片讀入到byte數(shù)組,然后添加到workbook中;最后調(diào)用的是patriarch.CreatePicture(anchor, pictureIdx)方法顯示圖片,而不是patriarch.CreateSimpleShape(anchor)方法。上面這段代碼執(zhí)行后生成的Excel文件樣式如下:

我們發(fā)現(xiàn),插入的圖片被拉伸填充在HSSFClientAnchor指定的區(qū)域。有時(shí)可能我們并不需要拉伸的效果,怎么辦呢?很簡(jiǎn)單,在最后加上這樣一句用來自動(dòng)調(diào)節(jié)圖片大小:

pict.Resize();

添加代碼后再執(zhí)行上述代碼,生成的Excel樣式如下:

圖片已經(jīng)自動(dòng)伸縮到原始大小了。

NPOI 1.2教程- 2.5打印相關(guān)設(shè)置

作者:Tony Qu

NPOI官方網(wǎng)站:http://npoi.codeplex.com/

打印設(shè)置主要包括方向設(shè)置、縮放、紙張?jiān)O(shè)置、頁邊距等。NPOI 1.2支持大部分打印屬性,能夠讓你輕松滿足客戶的打印需要。

首先是方向設(shè)置,Excel支持兩種頁面方向,即縱向和橫向。

在NPOI中如何設(shè)置呢?你可以通過HSSFSheet.PrintSetup.Landscape來設(shè)置,Landscape是布爾類型的,在英語中是橫向的意思。如果Landscape等于true,則表示頁面方向?yàn)闄M向;否則為縱向。

接著是縮放設(shè)置,

這里的縮放比例對(duì)應(yīng)于HSSFSheet.PrintSetup.Scale,而頁寬和頁高分別對(duì)應(yīng)于HSSFSheet.PrintSetup.FitWidth和HSSFSheet.PrintSetup.FitHeight。要注意的是,這里的PrintSetup.Scale應(yīng)該被設(shè)置為0-100之間的值,而不是小數(shù)。

接下來就是紙張?jiān)O(shè)置了,對(duì)應(yīng)于HSSFSheet.PrintSetup.PaperSize,但這里的PaperSize并不是隨便設(shè)置的,而是由一些固定的值決定的,具體的值與對(duì)應(yīng)的紙張如下表所示:

值紙張

1US Letter 8 1/2 x 11 in

2USLetter Small 8 1/2 x 11 in

3US Tabloid 11 x 17 in

4US Ledger 17 x 11 in

5US Legal 8 1/2 x 14 in

6US Statement 5 1/2 x 8 1/2 in

7US Executive 7 1/4 x 10 1/2 in

8A3 297 x 420 mm

9A4 210 x 297 mm

10A4 Small 210 x 297 mm

11A5 148 x 210 mm

12B4 (JIS) 250 x 354

13B5 (JIS) 182 x 257 mm

14Folio 8 1/2 x 13 in

15Quarto 215 x 275 mm

1610 x 14 in

1711 x 17 in

18US Note 8 1/2 x 11 in

19US Envelope #9 3 7/8 x 8 7/8

20US Envelope #10 4 1/8 x 9 1/2

21US Envelope #11 4 1/2 x 10 3/8

22US Envelope #12 4 \276 x 11

23US Envelope #14 5 x 11 1/2

24C size sheet

25D size sheet

26E size sheet

27Envelope DL 110 x 220mm

28Envelope C5 162 x 229 mm

29Envelope C3 324 x 458 mm

30Envelope C4 229 x 324 mm

31Envelope C6 114 x 162 mm

32Envelope C65 114 x 229 mm

33Envelope B4 250 x 353 mm

34Envelope B5 176 x 250 mm

35Envelope B6 176 x 125 mm

36Envelope 110 x 230 mm

37US Envelope Monarch 3.875 x 7.5 in

386 3/4 US Envelope 3 5/8 x 6 1/2 in

39US Std Fanfold 14 7/8 x 11 in

40German Std Fanfold 8 1/2 x 12 in

41German Legal Fanfold 8 1/2 x 13 in

42B4 (ISO) 250 x 353 mm

43Japanese Postcard 100 x 148 mm

449 x 11 in

4510 x 11 in

4615 x 11 in

47Envelope Invite 220 x 220 mm

48RESERVED--DO NOT USE

49RESERVED--DO NOT USE

50US Letter Extra 9 \275 x 12 in

51US Legal Extra 9 \275 x 15 in

52US Tabloid Extra 11.69 x 18 in

53A4 Extra 9.27 x 12.69 in

54Letter Transverse 8 \275 x 11 in

55A4 Transverse 210 x 297 mm

56Letter Extra Transverse 9\275 x 12 in

57SuperA/SuperA/A4 227 x 356 mm

58SuperB/SuperB/A3 305 x 487 mm

59US Letter Plus 8.5 x 12.69 in

60A4 Plus 210 x 330 mm

61A5 Transverse 148 x 210 mm

62B5 (JIS) Transverse 182 x 257 mm

63A3 Extra 322 x 445 mm

64A5 Extra 174 x 235 mm

65B5 (ISO) Extra 201 x 276 mm

66A2 420 x 594 mm

67A3 Transverse 297 x 420 mm

68A3 Extra Transverse 322 x 445 mm

69Japanese Double Postcard 200 x 148 mm

70A6 105 x 148 mm

71Japanese Envelope Kaku #2

72Japanese Envelope Kaku #3

73Japanese Envelope Chou #3

74Japanese Envelope Chou #4

75Letter Rotated 11 x 8 1/2 11 in

76A3 Rotated 420 x 297 mm

77A4 Rotated 297 x 210 mm

78A5 Rotated 210 x 148 mm

79B4 (JIS) Rotated 364 x 257 mm

80B5 (JIS) Rotated 257 x 182 mm

81Japanese Postcard Rotated 148 x 100 mm

82Double Japanese Postcard Rotated 148 x 200 mm

83A6 Rotated 148 x 105 mm

84Japanese Envelope Kaku #2 Rotated

85Japanese Envelope Kaku #3 Rotated

86Japanese Envelope Chou #3 Rotated

87Japanese Envelope Chou #4 Rotated

88B6 (JIS) 128 x 182 mm

89B6 (JIS) Rotated 182 x 128 mm

9012 x 11 in

91Japanese Envelope You #4

92Japanese Envelope You #4 Rotated

93PRC 16K 146 x 215 mm

94PRC 32K 97 x 151 mm

95PRC 32K(Big) 97 x 151 mm

96PRC Envelope #1 102 x 165 mm

97PRC Envelope #2 102 x 176 mm

98PRC Envelope #3 125 x 176 mm

99PRC Envelope #4 110 x 208 mm

100PRC Envelope #5 110 x 220 mm

101PRC Envelope #6 120 x 230 mm

102PRC Envelope #7 160 x 230 mm

103PRC Envelope #8 120 x 309 mm

104PRC Envelope #9 229 x 324 mm

105PRC Envelope #10 324 x 458 mm

106PRC 16K Rotated

107PRC 32K Rotated

108PRC 32K(Big) Rotated

109PRC Envelope #1 Rotated 165 x 102 mm

110PRC Envelope #2 Rotated 176 x 102 mm

111PRC Envelope #3 Rotated 176 x 125 mm

112PRC Envelope #4 Rotated 208 x 110 mm

113PRC Envelope #5 Rotated 220 x 110 mm

114PRC Envelope #6 Rotated 230 x 120 mm

115PRC Envelope #7 Rotated 230 x 160 mm

116PRC Envelope #8 Rotated 309 x 120 mm

117PRC Envelope #9 Rotated 324 x 229 mm

118PRC Envelope #10 Rotated 458 x 324 mm

(此表摘自《Excel Binary File Format (.xls) Structure Specification.pdf》)

HSSFSheet下面定義了一些xxxx_PAPERSIZE的常量,但都是非常常用的紙張大小,如果滿足不了你的需要,可以根據(jù)上表自己給PaperSize屬性賦值。所以,如果你要設(shè)置紙張大小可以用這樣的代碼:

HSSFSheet.PrintSetup.PaperSize=HSSFSheet.A4_PAPERSIZE;

HSSFSheet.PrintSetup.PaperSize=9;(A4 210*297mm)

再下來就是打印的起始頁碼,它對(duì)應(yīng)于HSSFSheet.PrintSetup.PageStart和HSSFSheet.PrintSetup.UsePage,如果UsePage=false,那么就相當(dāng)于“自動(dòng)”,這時(shí)PageStart不起作用;如果UsePage=true,PageStart才會(huì)起作用。所以在設(shè)置PageStart之前,必須先把UsePage設(shè)置為true。

“打印”欄中的“網(wǎng)格線”設(shè)置對(duì)應(yīng)于HSSFSheet.IsPrintGridlines,請(qǐng)注意,這里不是HSSFSheet.PrintSetup下面,所以別搞混了。這里之所以不隸屬于PrintSetup是由底層存儲(chǔ)該信息的record決定的,底層是把IsGridsPrinted放在GridsetRecord里面的,而不是PrintSetupRecord里面的,盡管界面上是放在一起的。另外還有一個(gè)HSSFSheet.IsGridsPrinted屬性,這個(gè)屬性對(duì)應(yīng)于底層的gridset Record,但這個(gè)record是保留的,從微軟的文檔顯示沒有任何意義,所以這個(gè)屬性請(qǐng)不要去設(shè)置。

“單色打印”則對(duì)應(yīng)于HSSFSheet.PrintSetup.NoColors,這是布爾類型的,值為true時(shí),表示單色打印。

“草稿品質(zhì)”對(duì)應(yīng)于HSSFSheet.PrintSetup.IsDraft,也是布爾類型的,值為true時(shí),表示用草稿品質(zhì)打印。

這里的打印順序是由HSSFSheet.PrintSetup.LeftToRight決定的,它是布爾類型的,當(dāng)為true時(shí),則表示“先行后列”;如果是false,則表示“先列后行”。

在NPOI 1.2中,“行號(hào)列標(biāo)”、“批注”和“錯(cuò)誤單元格打印為”、“頁邊距”暫不支持,將在以后的版本中支持。

有關(guān)打印的范例可以參考NPOI 1.2正式版中的SetPrintSettingsInXls項(xiàng)目。

2.6.1用NPOI操作EXCEL--調(diào)整表單顯示比例

在Excel中,可以通過調(diào)整右下角的滾動(dòng)條來調(diào)整Sheet的顯示比例。如圖:

在NPOI中,也能通過代碼實(shí)現(xiàn)這樣的功能,并且代碼非常簡(jiǎn)單:

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

sheet1.CreateRow(

0).CreateCell(0).SetCellValue("This?is?a?test.");

//50%?zoom

sheet1.SetZoom(1,2);

我們發(fā)現(xiàn),SetZoom有兩個(gè)參數(shù)。其中第一個(gè)參數(shù)表示縮放比例的分子,第二個(gè)參數(shù)表示縮放比例的分母,所以SetZoom(1,2)就表示縮小到1/2,也就是50%。代碼執(zhí)行后生成的Excel樣式如下:

如果將SetZoom的參數(shù)改成(2,1),代碼執(zhí)行后生成的Excel樣式如下,表示擴(kuò)大兩倍:

2.6.2用NPOI操作EXCEL--設(shè)置密碼

有時(shí),我們可能需要某些單元格只讀,如在做模板時(shí),模板中的數(shù)據(jù)是不能隨意讓別人改的。在Excel中,可以通過“審閱->保護(hù)工作表”來完成,如下圖:

那么,在NPOI中有沒有辦法通過編碼的方式達(dá)到這一效果呢?答案是肯定的。

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

HSSFRow?row1?=?sheet1.CreateRow(

0);

HSSFCell?cel1?=?row1.CreateCell(

0);

HSSFCell?cel2?=?row1.CreateCell(

1);

HSSFCellStyle?unlocked?=?hssfworkbook.CreateCellStyle();

unlocked.IsLocked?=

false;

HSSFCellStyle?locked?=?hssfworkbook.CreateCellStyle();

locked.IsLocked?=

true;

cel1.SetCellValue(

"沒被鎖定");

cel1.CellStyle?=?unlocked;

cel2.SetCellValue(

"被鎖定");

cel2.CellStyle?=?locked;

sheet1.ProtectSheet(

"password");

正如代碼中所看到的,我們通過設(shè)置CellStype的ISLocked為True,表示此單元格將被鎖定。相當(dāng)于在Excel中執(zhí)行了如下操作:

然后通過ProtectSheet設(shè)置密碼。

執(zhí)行結(jié)果如下:

沒被鎖定的列可以任意修改。

被鎖定的列不能修改。

輸入密碼可以解除鎖定。

NPOI 1.2教程-組合行、列

作者:Tony Qu

NPOI官方網(wǎng)站:http://npoi.codeplex.com/

Excel 2007中有一個(gè)面板是專門用于設(shè)置組合功能的,叫做“分級(jí)顯示”面板,如下所示:

可能我們?cè)谶^去生成Excel文件的時(shí)候根本不會(huì)用這個(gè)功能,也沒辦法用,因?yàn)閏vs法和html法沒辦法控制這些東西。這里簡(jiǎn)單的介紹一下什么叫做組合:

組合分為行組合和列組合,所謂行組合,就是讓n行組合成一個(gè)集合,能夠進(jìn)行展開和合攏操作,在Excel中顯示如下:

圖中左側(cè)就是用于控制行組合折疊的圖標(biāo),圖中上部就是用于控制列組合的,是不是有點(diǎn)像TreeView中的折疊節(jié)點(diǎn)?很多時(shí)候由于數(shù)據(jù)太多,為了讓用戶對(duì)于大量數(shù)據(jù)一目了然,我們可以使用行列組合來解決顯示大綱,這和Visual Studio里面的region的概念是類似的。

細(xì)心的朋友可能已經(jīng)注意到了,我們其實(shí)可以對(duì)一行做多次組合操作,這就是分級(jí)顯示的概念,圖中就把行2-3分為2個(gè)組合,第2行到第4行為一個(gè)組合,第2行到第5行一個(gè)組合,所以是分兩級(jí)。

在NPOI中,要實(shí)現(xiàn)分組其實(shí)并不難,你只需要調(diào)用HSSFSheet.GroupRow和HSSFSheet.GroupColumn這兩個(gè)方法就可以了。

首先我們來看HSSFSheet.GroupRow,GroupRow有2個(gè)參數(shù),分別是fromRow和toRow,表示起始行號(hào)和結(jié)束行號(hào),這些行號(hào)都是從0開始算起的。

HSSFWorkbookhssfworkbook =newHSSFWorkbook();

HSSFSheet s =hssfworkbook.CreateSheet("Sheet1");

s.GroupRow(1,3);

上面的代碼把第2行到第4行做了組合。

要組合列,其實(shí)代碼很相似,如下所示:

s.GroupColumn(1,3)

上面的代碼把B至D列做了組合。

正如上圖中Excel的“分級(jí)顯示”面板所示,有“組合”,也一定有“取消組合”,NPOI中你可以用HSSFSheet.UngroupRow和HSSFSheet.UngroupColumn,參數(shù)和GroupXXX是一樣的,如果要取消第2到第4行的組合,就可以用下面的代碼:

s.UngroupColumn(1,3)

相關(guān)范例請(qǐng)見NPOI 1.2正式版中的GroupRowAndColumnInXls項(xiàng)目。

2.6.4用NPOI操作EXCEL--鎖定列

在Excel中,有時(shí)可能會(huì)出現(xiàn)列數(shù)太多或是行數(shù)太多的情況,這時(shí)可以通過鎖定列來凍結(jié)部分列,不隨滾動(dòng)條滑動(dòng),方便查看。在Excel中設(shè)置凍結(jié)列的方法如下:

同樣,利用NPOI,通過代碼也能實(shí)現(xiàn)上面的效果:

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

HSSFRow?row1?=?sheet1.CreateRow(

0);

row1.CreateCell(

0).SetCellValue("凍結(jié)列");

sheet1.CreateFreezePane(

1,0,1,0);

代碼執(zhí)行結(jié)果如下:

下面對(duì)CreateFreezePane的參數(shù)作一下說明:第一個(gè)參數(shù)表示要凍結(jié)的列數(shù);第二個(gè)參數(shù)表示要凍結(jié)的行數(shù),這里只凍結(jié)列所以為0;第三個(gè)參數(shù)表示右邊區(qū)域可見的首列序號(hào),從1開始計(jì)算;第四個(gè)參數(shù)表示下邊區(qū)域可見的首行序號(hào),也是從1開始計(jì)算,這里是凍結(jié)列,所以為0;

舉例說明也許更好理解,將各參數(shù)設(shè)置為如下:

sheet1.CreateFreezePane(2,0,5,0);

得到的效果如下圖:

注意圖中C、D和E列默認(rèn)是看不到的,滾動(dòng)才看得到,這就是第三個(gè)參數(shù)5起了作用,是不是很好理解了呢:)

接下來,看一下凍結(jié)行的效果。將上面的代碼稍作修改:

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

HSSFRow?row1?=?sheet1.CreateRow(

0);

row1.CreateCell(

0).SetCellValue("凍結(jié)行");

sheet1.CreateFreezePane(

0,1,0,1);

執(zhí)行后生成的Excel文件效果見下圖:

那么,如果要行和列同時(shí)凍結(jié)該怎么做呢?聰明的你一定能想得到,呵呵~~

NPOI 1.2教程-顯示/隱藏Excel網(wǎng)格線

作者:Tony Qu

NPOI官方網(wǎng)站:http://npoi.codeplex.com/

有些時(shí)候,我們需要網(wǎng)格線,而有些時(shí)候我們不需要,這取決于實(shí)際的業(yè)務(wù)需求。前兩天inmegin兄就問我,怎么把網(wǎng)格給去掉,因?yàn)樗麄円袳xcel文檔當(dāng)Word使,也許是因?yàn)镋xcel排版方便吧。

Excel中的網(wǎng)格線設(shè)置是以表(Sheet)為單位進(jìn)行管理的,這也就意味著你可以讓一個(gè)表顯示網(wǎng)格線,而另一個(gè)表不顯示,這是不沖突的。

在Excel 2007中,我們通常用“工作表選項(xiàng)”面板來設(shè)置這個(gè)屬性:

在面板中,你會(huì)發(fā)現(xiàn)有2個(gè)多選框,一個(gè)是查看,一個(gè)是打印,也就是說Excel是把查看和打印網(wǎng)格線作為兩個(gè)設(shè)置來處理的,存儲(chǔ)的Record也是不同的。

在NPOI中,如果要讓網(wǎng)格線在查看時(shí)顯示/隱藏,你可以HSSFSheet.DisplayGridlines屬性,默認(rèn)值為true(這也是為什么默認(rèn)情況下我們能夠看到網(wǎng)格線)。下面的代碼就是讓網(wǎng)格線在查看時(shí)不可見的:

HSSFWorkbookhssfworkbook =newHSSFWorkbook();

HSSFSheet s1= hssfworkbook.CreateSheet("Sheet1");

s1.DisplayGridlines=false;

如果要在打印時(shí)顯示/隱藏網(wǎng)格線,你可以用HSSFSheet.IsGridlinesPrinted屬性,默認(rèn)值為false(這就是默認(rèn)情況下打印看不到網(wǎng)格線的原因)。代碼和上面差不多:

s1.IsGridsPrinted=true;

上面的代碼將在打印時(shí)顯示網(wǎng)格線,打印的效果如下所示。

在此也提醒大家,如果這個(gè)Excel最終客戶有打印意向,可別忘了把IsGridPrinted屬性也設(shè)置上。

相關(guān)范例可以參考NPOI 1.2正式版中的DisplayGridlinesInXls項(xiàng)目。

2.6.6用NPOI操作EXCEL--設(shè)置初始視圖的行、列

有些時(shí)候,我們可能希望生成的Excel文件在被打開的時(shí)候自動(dòng)將焦點(diǎn)定位在某個(gè)單元格或是選中某個(gè)區(qū)域中。在NPOI中可以通過SetAsActiveCell和SetActiveCellRange等幾個(gè)方法實(shí)現(xiàn)。

首先我們看一下設(shè)置初始視圖中選中某個(gè)單元格的方法:

//use?HSSFCell.SetAsActiveCell()?to?select?B6?as?the?active?column

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet?A");

CreateCellArray(sheet1);

sheet1.GetRow(

5).GetCell(1).SetAsActiveCell();

//set?TopRow?and?LeftCol?to?make?B6?the?first?cell?in?the?visible?area

sheet1.TopRow?=5;

sheet1.LeftCol?=

1;

其中CreateCellArray(sheet1)方法用來寫示范數(shù)據(jù),其代碼為(下同):

staticvoidCreateCellArray(HSSFSheet?sheet)

{

for(inti?=0;?i?<300;?i++)

{

HSSFRow?row=sheet.CreateRow(i);

for(intj?=0;?j?<150;?j++)

{

HSSFCell?cell?=?row.CreateCell(j);

cell.SetCellValue(i*j);

}

}

}

生成的Excel打開時(shí)效果如下,注意B6為默認(rèn)選中狀態(tài),TopRow和LeftCol設(shè)置B6為當(dāng)前可見區(qū)域的第一個(gè)單元格:

如果不設(shè)置TopRow和LeftCol屬性,默認(rèn)的可見域的第一個(gè)單元格為A1,如下是另一種設(shè)置活動(dòng)單元格的方法,但沒有設(shè)置此Sheet的TopRow和LeftCol:

HSSFSheet?sheet2?=?hssfworkbook.CreateSheet("Sheet?B");

sheet2.Sheet.SetActiveCell(

1,5);

對(duì)應(yīng)生成的Excel顯示為:

除了設(shè)置某個(gè)單元格為選中狀態(tài)外,還NPOI可以設(shè)置某個(gè)區(qū)域?yàn)檫x中狀態(tài):

//use?Sheet.SetActiveCellRange?to?select?a?cell?range

HSSFSheet?sheet3?=?hssfworkbook.CreateSheet("Sheet?C");

CreateCellArray(sheet3);

sheet3.Sheet.SetActiveCellRange(

2,5,1,5);

以上代碼設(shè)置了Sheet C的選中區(qū)域?yàn)锽3:F6:

還有更強(qiáng)大的,設(shè)置多個(gè)選中區(qū)域:

//use?Sheet.SetActiveCellRange?to?select?multiple?cell?ranges

HSSFSheet?sheet4?=?hssfworkbook.CreateSheet("Sheet?D");

CreateCellArray(sheet4);

List?cellranges?=

newList();

cellranges.Add(

newCellRangeAddress8Bit(1,3,2,5));

cellranges.Add(

newCellRangeAddress8Bit(6,7,8,9));

sheet4.Sheet.SetActiveCellRange(cellranges,

1,6,9);

如果一個(gè)Excel文件中有多個(gè)Sheet,還可以通過如下語句設(shè)置打開時(shí)的初始Sheet:

hssfworkbook.ActiveSheetIndex?=2;

2.6.7用NPOI操作EXCEL--數(shù)據(jù)有效性

在有些情況下(比如Excel引入),我們可能不允許用戶在Excel隨意輸入一些無效數(shù)據(jù),這時(shí)就要在模板中加一些數(shù)據(jù)有效性的驗(yàn)證。在Excel中,設(shè)置數(shù)據(jù)有效性的方步驟如下:(1)先選定一個(gè)區(qū)域;數(shù)據(jù)有效性”中設(shè)置數(shù)據(jù)有效性驗(yàn)證(如圖)。à(2)在菜單“數(shù)據(jù)

同樣,利用NPOI,用代碼也可以實(shí)現(xiàn):

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

sheet1.CreateRow(

0).CreateCell(0).SetCellValue("日期列");

CellRangeAddressList?regions1?=

newCellRangeAddressList(1,65535,0,0);

DVConstraint?constraint1?=?DVConstraint.CreateDateConstraint(DVConstraint.OperatorType.BETWEEN,

"1900-01-01","2999-12-31","yyyy-MM-dd");

HSSFDataValidation?dataValidate1?=

newHSSFDataValidation(regions1,?constraint1);

dataValidate1.CreateErrorBox(

"error","You?must?input?a?date.");

sheet1.AddValidationData(dataValidate1);

上面是一個(gè)在第一列要求輸入1900-1-1至2999-12-31之間日期的有效性驗(yàn)證的例子,生成的Excel效果如下,當(dāng)輸入非法時(shí)將給出警告:

下面對(duì)剛才用到的幾個(gè)方法加以說明:

CellRangeAddressList

類表示一個(gè)區(qū)域,構(gòu)造函數(shù)中的四個(gè)參數(shù)分別表示起始行序號(hào),終止行序號(hào),起始列序號(hào),終止列序號(hào)。所以第一列所在區(qū)域就表示為:

//所有序號(hào)都從零算起,第一行標(biāo)題行除外,所以第一個(gè)參數(shù)是1,65535是一個(gè)Sheet的最大行數(shù)newCellRangeAddressList(1,65535,0,0);

另外,CreateDateConstraint的第一個(gè)參數(shù)除了設(shè)置成DVConstraint.OperatorType.BETWEEN外,還可以設(shè)置成如下一些值,大家可以自己一個(gè)個(gè)去試看看效果:

最后,dataValidate1.CreateErrorBox(title,text),用來創(chuàng)建出錯(cuò)時(shí)的提示信息。第一個(gè)參數(shù)表示提示框的標(biāo)題,第二個(gè)參數(shù)表示提示框的內(nèi)容。

理解了上面這些,創(chuàng)建一個(gè)整數(shù)類型的有效性驗(yàn)證也不難實(shí)現(xiàn):

sheet1.CreateRow(0).CreateCell(1).SetCellValue("數(shù)值列");

CellRangeAddressList?regions2?=

newCellRangeAddressList(1,65535,1,1);

DVConstraint?constraint2?=?DVConstraint.CreateNumericConstraint(DVConstraint.ValidationType.INTEGER,DVConstraint.OperatorType.BETWEEN,

"0","100");

HSSFDataValidation?dataValidate2?=

newHSSFDataValidation(regions2,?constraint2);

dataValidate2.CreateErrorBox(

"error","You?must?input?a?numeric?between?0?and?100.");

sheet1.AddValidationData(dataValidate2);

生成的Excel效果為:

下一節(jié)我們將學(xué)習(xí)利用數(shù)據(jù)有效性創(chuàng)建下拉列表的例子。

2.6.8用NPOI操作EXCEL--生成下拉列表

上一節(jié)我們講了簡(jiǎn)單的數(shù)據(jù)有效性驗(yàn)證,這一節(jié)我們學(xué)習(xí)一下數(shù)據(jù)有效性的另一個(gè)應(yīng)用--下拉列表。在Excel中,并沒有類似Web中的下拉控件,其下拉效果是通過數(shù)據(jù)有效性來實(shí)現(xiàn)的。設(shè)置步驟為:(1)選定一個(gè)要生成下拉列表的區(qū)域;(2)設(shè)置數(shù)據(jù)有效性為序列,并在來源中填充可選下拉的值,用“,”隔開(如圖)。

對(duì)應(yīng)的效果為:

同樣,利用NPOI代碼也可以實(shí)現(xiàn)上面的效果:

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

CellRangeAddressList?regions?=

newCellRangeAddressList(0,65535,0,0);

DVConstraint?constraint?=?DVConstraint.CreateExplicitListConstraint(

newstring[]?{"itemA","itemB","itemC"});

HSSFDataValidation?dataValidate?=

newHSSFDataValidation(regions,?constraint);

sheet1.AddValidationData(dataValidate);

下面對(duì)代碼作一下簡(jiǎn)要說明:先設(shè)置一個(gè)需要提供下拉的區(qū)域,關(guān)于CellRangeAddressList構(gòu)造函數(shù)參數(shù)的說明請(qǐng)參見上一節(jié)

CellRangeAddressList?regions?=newCellRangeAddressList(0,65535,0,0);

然后將下拉項(xiàng)作為一個(gè)數(shù)組傳給CreateExplicitListConstraint作為參數(shù)創(chuàng)建一個(gè)約束,根據(jù)要控制的區(qū)域和約束創(chuàng)建數(shù)據(jù)有效性就可以了。

但是這樣會(huì)有一個(gè)問題:Excel中允許輸入的序列來源長(zhǎng)度最大為255個(gè)字符,也就是說當(dāng)下拉項(xiàng)的總字符串長(zhǎng)度超過255是將會(huì)出錯(cuò)。那么如果下拉項(xiàng)很多的情況下應(yīng)該怎么處理呢?答案是通過引用的方式。步驟如下:先創(chuàng)建一個(gè)Sheet專門用于存儲(chǔ)下拉項(xiàng)的值,并將各下拉項(xiàng)的值寫入其中:

HSSFSheet?sheet2?=?hssfworkbook.CreateSheet("ShtDictionary");

sheet2.CreateRow(

0).CreateCell(0).SetCellValue("itemA");

sheet2.CreateRow(

1).CreateCell(0).SetCellValue("itemB");

sheet2.CreateRow(

2).CreateCell(0).SetCellValue("itemC");

然后定義一個(gè)名稱,指向剛才創(chuàng)建的下拉項(xiàng)的區(qū)域:

HSSFName?range?=?hssfworkbook.CreateName();

range.Reference?=

"ShtDictionary!$A1:$A3";

range.NameName?=

"dicRange";

最后,設(shè)置數(shù)據(jù)約束時(shí)指向這個(gè)名稱而不是字符數(shù)組:

HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");

CellRangeAddressList?regions?=

newCellRangeAddressList(0,65535,0,0);

DVConstraint?constraint?=?DVConstraint.CreateFormulaListConstraint(

"dicRange");

HSSFDataValidation?dataValidate?=

newHSSFDataValidation(regions,?constraint);

sheet1.AddValidationData(dataValidate);

執(zhí)行這段代碼,生成的Excel效果如下:

在名稱管理器中會(huì)發(fā)現(xiàn)有一個(gè)名為"dicRange"的名稱,指向"ShtDictionary!$A1:$A3"的下拉項(xiàng)區(qū)域:

在數(shù)據(jù)有效性中會(huì)發(fā)現(xiàn)來源變成了"=dicRange",指向上面定義的名稱。而不是以前的"itemA,itemB,itemC":

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)自鏈接 目錄 1.認(rèn)識(shí)NPOI 2.使用NPOI生成xls文件 2.1創(chuàng)建基本內(nèi)容 2.1.1創(chuàng)建Workboo...
    腿毛褲閱讀 11,143評(píng)論 1 3
  • 使用首先需要了解他的工作原理 1.POI結(jié)構(gòu)與常用類 (1)創(chuàng)建Workbook和Sheet (2)創(chuàng)建單元格 (...
    長(zhǎng)城ol閱讀 8,737評(píng)論 2 25
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,537評(píng)論 19 139
  • 戚寵閱讀 217評(píng)論 0 0
  • 再一次看到可愛的克老師,今天竟然穿了二十多年前剛開始來臺(tái)灣講課時(shí)買的襯衣。 他覺得今天是生命教練聯(lián)教育中心落戶長(zhǎng)沙...
    志玲覺知生活閱讀 765評(píng)論 0 1

友情鏈接更多精彩內(nèi)容