Windows中使用Java生成Excel文件并插入圖片的方法
生成簡單的Excel文件
在現(xiàn)實(shí)的辦公中,我們常常會有這樣一個要求:要求把報(bào)表直接用excel打開。在實(shí)習(xí)中有這樣一個需求。根據(jù)所選擇的資源查詢用戶所提供附件的全部信息并生成excel供下載。但是在查詢的時候我們需要來檢測用戶所提供的附件里面的信息是否有錯誤(身份證)。有錯誤的生成錯誤信息excel。
Apache的POI項(xiàng)目,是目前比較成熟的HSSF接口,用來處理Excel對象。其實(shí)POI不僅僅只能處理excel,它還可以處理word、PowerPoint、Visio、甚至Outlook。
這里我先介紹利用POI如何生成excel。
首先在生成Excel前,我們需要理解一下Excel文件的組織形式。在POI中,是這樣理解的:一個Excel文件對應(yīng)一個workbook,一個workerbook是有若干個sheet組成的。一個sheet有多個row,一個row一般存在多個cell。
對于上面的四個名詞我們可以在下圖理解

對于生成Excel,POI提供了如下幾個基本對象:
- HSSFWorkbook:excel 的文檔對象
- HSSFSheet:excel 的表單
- HSSFRow :excel 的行
- HSSFCell:excel 的格子單元
從上面的圖片和Excel的組織結(jié)構(gòu),我們就可以明白創(chuàng)建Excel的步驟。
1、生成文檔對象HSSHWorkbook。
2、通過HSSFWorkbook生成表單HSSFSheet。
3、通過HSSFSheet生成行HSSFRow
4、通過HSSFRow生成單元格HSSFCell。
下面是展示代碼:
身份證錯誤Bean(ErrorCondition.java)
public class ErrorCondition {
private String name; // 姓名
private String idCard; // 身份證
private String status; // 錯誤狀態(tài)
private String message; // 錯誤信息
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)
public class ExportErrorExcel {
public static void main(String[] args) {
//第一步創(chuàng)建workbook
HSSFWorkbook wb = new HSSFWorkbook();
//第二步創(chuàng)建sheet
HSSFSheet sheet = wb.createSheet("身份證錯誤信息");
//第三步創(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); //第一個單元格
cell.setCellValue("姓名"); //設(shè)定值
cell.setCellStyle(style); //內(nèi)容居中
cell = row.createCell(1); //第二個單元格
cell.setCellValue("身份證");
cell.setCellStyle(style);
cell = row.createCell(2); //第三個單元格
cell.setCellValue("錯誤狀態(tài)");
cell.setCellStyle(style);
cell = row.createCell(3); //第四個單元格
cell.setCellValue("錯誤信息");
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", "長度錯誤");
ErrorCondition r2 = new ErrorCondition("李四", "430682198902191112","X", "校驗(yàn)錯誤");
ErrorCondition r3 = new ErrorCondition("王五", "", "N", "身份證信息為空");
list.add(r1);
list.add(r2);
list.add(r3);
return list;
}
}
通過上面六個步驟就可以在指定的位置生成Excel文件了。

java POI實(shí)現(xiàn)向Excel中插入圖片
做Web開發(fā)免不了要與Excel打交道。今天老大給我一個任務(wù)-導(dǎo)出Excel。開始想的還是蠻簡單的,無非就是查找,構(gòu)建Excel,response下載即可。但是有一點(diǎn)不同,就是要加入圖片,就是這個加入圖片搞了好久。同時網(wǎng)絡(luò)上確實(shí)沒有發(fā)現(xiàn)比較好的資料,所以寫這篇博文記錄之,供自己和博友們查詢,參考。
在POI中有HSSFPatriarch對象,該對象為畫圖的頂級管理器,它的createPicture(anchor, pictureIndex)方法就能夠在Excel插入一張圖片。所以要在Excel中插入圖片,三步就可以搞定。一、獲取HSSFPatriarch對象,二、new HSSFClientAnchor對象,三、調(diào)用createPicture方法即可。實(shí)現(xiàn)倒是非常容易實(shí)現(xiàn),如果想把它做好還是有點(diǎn)兒難度的。這里我們先插入一張圖片:
public class ExcelImageTest {
public static void main(String[] args) {
FileOutputStream fileOut = null;
BufferedImage bufferImg = null;
//先把讀進(jìn)來的圖片放到一個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");
//畫圖的頂級管理器,一個sheet只能獲取一個(一定要注意這點(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:/測試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é)果:

至于為什么會是這樣的結(jié)果,主要是因?yàn)镠SSFClientAnchor(0, 0, 255, 255,(short) 1, 1, (short) 5, 8)這個構(gòu)造函數(shù)造成的,下面我就來解釋這個構(gòu)造函數(shù):HSSFClientAnchor(int dx1,int dy1,int dx2,int dy2,short col1,int row1,short col2, int row2);各個參數(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òu)造函數(shù)所創(chuàng)建的,從這幅圖中我們可以清晰看到上面八個參數(shù)的含義和不同之處。

上面是插入一張圖片,那么實(shí)現(xiàn)插入多張圖片呢?其實(shí)很簡單,構(gòu)造多個不同的HSSFClientAnchor對象,控制好那八個參數(shù),如下:
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é)果:

相關(guān)文章
基于Spring AOP @AspectJ進(jìn)階說明
這篇文章主要介紹了基于Spring AOP @AspectJ進(jìn)階說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
collection集合體系與并發(fā)修改異常的解決方法
今天小編就為大家分享一篇關(guān)于collection集合體系與并發(fā)修改異常的解決方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-03-03
Monaco?Editor實(shí)現(xiàn)sql和java代碼提示實(shí)現(xiàn)示例
這篇文章主要為大家介紹了Monaco?Editor代碼提示sql和java實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
使用Jackson實(shí)現(xiàn)Map與Bean互轉(zhuǎn)方式
這篇文章主要介紹了使用Jackson實(shí)現(xiàn)Map與Bean互轉(zhuǎn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
idea中導(dǎo)入別人的springboot項(xiàng)目的方法(圖文)
這篇文章主要介紹了idea中導(dǎo)入別人的springboot項(xiàng)目的方法(圖文),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
MybatisPlus 自動填充的實(shí)現(xiàn)
這篇文章主要介紹了MybatisPlus 自動填充的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Java?Collection接口中的常用方法總結(jié)
這篇文章將大概用代碼案例簡單總結(jié)一下?Collection?接口中的一些方法,我們會以他的實(shí)現(xiàn)類?Arraylist?為例創(chuàng)建對象??煲黄饋砜纯窗?/div> 2022-12-12
Java中消息隊(duì)列任務(wù)的平滑關(guān)閉詳解
對于消息隊(duì)列的監(jiān)聽,我們一般使用Java寫一個獨(dú)立的程序,在Linux服務(wù)器上運(yùn)行。程序啟動后,通過消息隊(duì)列客戶端接收消息,放入一個線程池進(jìn)行異步處理,并發(fā)的快速處理。這篇文章主要給大家介紹了關(guān)于Java中消息隊(duì)列任務(wù)的平滑關(guān)閉的相關(guān)資料,需要的朋友可以參考下。2017-11-11
如何使用Collections.reverse對list集合進(jìn)行降序排序
這篇文章主要介紹了Java使用Collections.reverse對list集合進(jìn)行降序排序,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11最新評論

