生成簡(jiǎn)單的Excel文件
在現(xiàn)實(shí)的辦公中,我們常常會(huì)有這樣一個(gè)要求:要求把報(bào)表直接用excel打開。在實(shí)習(xí)中有這樣一個(gè)需求。根據(jù)所選擇的資源查詢用戶所提供附件的全部信息并生成excel供下載。但是在查詢的時(shí)候我們需要來檢測(cè)用戶所提供的附件里面的信息是否有錯(cuò)誤(身份證)。有錯(cuò)誤的生成錯(cuò)誤信息excel。
Apache的POI項(xiàng)目,是目前比較成熟的HSSF接口,用來處理Excel對(duì)象。其實(shí)POI不僅僅只能處理excel,它還可以處理word、PowerPoint、Visio、甚至Outlook。
這里我先介紹利用POI如何生成excel。
首先在生成Excel前,我們需要理解一下Excel文件的組織形式。在POI中,是這樣理解的:一個(gè)Excel文件對(duì)應(yīng)一個(gè)workbook,一個(gè)workerbook是有若干個(gè)sheet組成的。一個(gè)sheet有多個(gè)row,一個(gè)row一般存在多個(gè)cell。
對(duì)于上面的四個(gè)名詞我們可以在下圖理解
對(duì)于生成Excel,POI提供了如下幾個(gè)基本對(duì)象:
- HSSFWorkbook:excel 的文檔對(duì)象
- HSSFSheet:excel 的表單
- HSSFRow :excel 的行
- HSSFCell:excel 的格子單元
從上面的圖片和Excel的組織結(jié)構(gòu),我們就可以明白創(chuàng)建Excel的步驟。
1、生成文檔對(duì)象HSSHWorkbook。
2、通過HSSFWorkbook生成表單HSSFSheet。
3、通過HSSFSheet生成行HSSFRow
4、通過HSSFRow生成單元格HSSFCell。
下面是展示代碼:
身份證錯(cuò)誤Bean(ErrorCondition.java)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
public class ErrorCondition { private String name; // 姓名 private String idCard; // 身份證 private String status; // 錯(cuò)誤狀態(tài) private String message; // 錯(cuò)誤信息 ErrorCondition(String name,String idCard,String status,String message){ this .name = name; this .idCard = idCard; this .status = status; this .message = message; } public String getName() { return name; } public void setName(String name) { this .name = name; } public String getIdCard() { return idCard; } public void setIdCard(String idCard) { this .idCard = idCard; } public String getStatus() { return status; } public void setStatus(String status) { this .status = status; } public String getMessage() { return message; } public void setMessage(String message) { this .message = message; } } |
處理類(ExportErrorExcel.java)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
public class ExportErrorExcel { public static void main(String[] args) { //第一步創(chuàng)建workbook HSSFWorkbook wb = new HSSFWorkbook(); //第二步創(chuàng)建sheet HSSFSheet sheet = wb.createSheet( "身份證錯(cuò)誤信息" ); //第三步創(chuàng)建行row:添加表頭0行 HSSFRow row = sheet.createRow( 0 ); HSSFCellStyle style = wb.createCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); //居中 //第四步創(chuàng)建單元格 HSSFCell cell = row.createCell( 0 ); //第一個(gè)單元格 cell.setCellValue( "姓名" ); //設(shè)定值 cell.setCellStyle(style); //內(nèi)容居中 cell = row.createCell( 1 ); //第二個(gè)單元格 cell.setCellValue( "身份證" ); cell.setCellStyle(style); cell = row.createCell( 2 ); //第三個(gè)單元格 cell.setCellValue( "錯(cuò)誤狀態(tài)" ); cell.setCellStyle(style); cell = row.createCell( 3 ); //第四個(gè)單元格 cell.setCellValue( "錯(cuò)誤信息" ); cell.setCellStyle(style); //第五步插入數(shù)據(jù) List<ErrorCondition> list = ExportErrorExcel.getErrorCondition(); for ( int i = 0 ; i < list.size(); i++) { ErrorCondition errorCondition = list.get(i); //創(chuàng)建行 row = sheet.createRow(i+ 1 ); //創(chuàng)建單元格并且添加數(shù)據(jù) row.createCell( 0 ).setCellValue(errorCondition.getName()); row.createCell( 1 ).setCellValue(errorCondition.getIdCard()); row.createCell( 2 ).setCellValue(errorCondition.getStatus()); row.createCell( 3 ).setCellValue(errorCondition.getMessage()); } //第六步將生成excel文件保存到指定路徑下 try { FileOutputStream fout = new FileOutputStream( "D:\\errorCondition.xls" ); wb.write(fout); fout.close(); } catch (IOException e) { e.printStackTrace(); } System.out.println( "Excel文件生成成功..." ); } public static List<ErrorCondition> getErrorCondition(){ List<ErrorCondition> list = new ArrayList<ErrorCondition>(); ErrorCondition r1 = new ErrorCondition( "張三" , "4306821989021611" , "L" , "長(zhǎng)度錯(cuò)誤" ); ErrorCondition r2 = new ErrorCondition( "李四" , "430682198902191112" , "X" , "校驗(yàn)錯(cuò)誤" ); ErrorCondition r3 = new ErrorCondition( "王五" , "" , "N" , "身份證信息為空" ); list.add(r1); list.add(r2); list.add(r3); return list; } } |
通過上面六個(gè)步驟就可以在指定的位置生成Excel文件了。
java POI實(shí)現(xiàn)向Excel中插入圖片
做Web開發(fā)免不了要與Excel打交道。今天老大給我一個(gè)任務(wù)-導(dǎo)出Excel。開始想的還是蠻簡(jiǎn)單的,無非就是查找,構(gòu)建Excel,response下載即可。但是有一點(diǎn)不同,就是要加入圖片,就是這個(gè)加入圖片搞了好久。同時(shí)網(wǎng)絡(luò)上確實(shí)沒有發(fā)現(xiàn)比較好的資料,所以寫這篇博文記錄之,供自己和博友們查詢,參考。
在POI中有HSSFPatriarch對(duì)象,該對(duì)象為畫圖的頂級(jí)管理器,它的createPicture(anchor, pictureIndex)方法就能夠在Excel插入一張圖片。所以要在Excel中插入圖片,三步就可以搞定。一、獲取HSSFPatriarch對(duì)象,二、new HSSFClientAnchor對(duì)象,三、調(diào)用createPicture方法即可。實(shí)現(xiàn)倒是非常容易實(shí)現(xiàn),如果想把它做好還是有點(diǎn)兒難度的。這里我們先插入一張圖片:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
public class ExcelImageTest { public static void main(String[] args) { FileOutputStream fileOut = null ; BufferedImage bufferImg = null ; //先把讀進(jìn)來的圖片放到一個(gè)ByteArrayOutputStream中,以便產(chǎn)生ByteArray try { ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); bufferImg = ImageIO.read( new File( "F:/圖片/照片/無名氏/小昭11.jpg" )); ImageIO.write(bufferImg, "jpg" , byteArrayOut); HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet1 = wb.createSheet( "test picture" ); //畫圖的頂級(jí)管理器,一個(gè)sheet只能獲取一個(gè)(一定要注意這點(diǎn)) HSSFPatriarch patriarch = sheet1.createDrawingPatriarch(); //anchor主要用于設(shè)置圖片的屬性 HSSFClientAnchor anchor = new HSSFClientAnchor( 0 , 0 , 255 , 255 ,( short ) 1 , 1 , ( short ) 5 , 8 ); anchor.setAnchorType( 3 ); //插入圖片 patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG)); fileOut = new FileOutputStream( "D:/測(cè)試Excel.xls" ); // 寫入excel文件 wb.write(fileOut); System.out.println( "----Excle文件已生成------" ); } catch (Exception e) { e.printStackTrace(); } finally { if (fileOut != null ){ try { fileOut.close(); } catch (IOException e) { e.printStackTrace(); } } } } } |
如下為執(zhí)行后的結(jié)果:
至于為什么會(huì)是這樣的結(jié)果,主要是因?yàn)镠SSFClientAnchor(0, 0, 255, 255,(short) 1, 1, (short) 5, 8)這個(gè)構(gòu)造函數(shù)造成的,下面我就來解釋這個(gè)構(gòu)造函數(shù):HSSFClientAnchor(int dx1,int dy1,int dx2,int dy2,short col1,int row1,short col2, int row2);各個(gè)參數(shù)的含義如下:
- dx1:the x coordinate within the first cell。
- dy1:the y coordinate within the first cell。
- dx2:the x coordinate within the second cell。
- dy2:the y coordinate within the second cell。
- col1:the column (0 based) of the first cell。
- row1:the row (0 based) of the first cell。
- col2:the column (0 based) of the second cell。
- row2:the row (0 based) of the second cell。
這里dx1、dy1定義了該圖片在開始cell的起始位置,dx2、dy2定義了在終cell的結(jié)束位置。col1、row1定義了開始cell、col2、row2定義了結(jié)束cell。
下面是有兩個(gè)不同的構(gòu)造函數(shù)所創(chuàng)建的,從這幅圖中我們可以清晰看到上面八個(gè)參數(shù)的含義和不同之處。
上面是插入一張圖片,那么實(shí)現(xiàn)插入多張圖片呢?其實(shí)很簡(jiǎn)單,構(gòu)造多個(gè)不同的HSSFClientAnchor對(duì)象,控制好那八個(gè)參數(shù),如下:
1
2
3
4
5
6
|
HSSFClientAnchor anchor1 = new HSSFClientAnchor( 0 , 0 , 1023 , 100 ,( short ) 1 , 1 , ( short ) 5 , 8 ); HSSFClientAnchor anchor2 = new HSSFClientAnchor( 0 , 0 , 1023 , 100 ,( short ) 1 , 9 , ( short ) 5 , 16 ); //插入圖片 patriarch.createPicture(anchor1, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG)); patriarch.createPicture(anchor2, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG)); |
其余代碼一樣,得到如下結(jié)果: