最近遇到點讀取 Excel 數據的問題,于是花了點時間找開源工具。
要解析 Excel,首當其沖的是上傳文件,以前在項目里我們用 SmartUpload 進行上傳,不過這個項目似乎已經停止開發了,于是在這里我使用 Apache Commons FileUpload,可以在 http://jakarta.apache.org/commons/fileupload 找到。目前該項目的最新版本是 1.1.1,網上有大量的范例程序,不過后來用的時候發現大部分方法在新版本中都不推薦使用了,于是好好讀了一回 API 和官方范例。
先來看看如何上傳文件,Servlet 很簡單,在這里我限制了最大上傳量為 1M,且直接讀進內存中,不進行磁盤臨時文件緩存。
import
?java.io.IOException;
import ?java.io.PrintWriter;
import ?java.io.File;
import ?java.net.URI;
import ?java.net.URL;
import ?javax.servlet.ServletException;
import ?javax.servlet.http.HttpServlet;
import ?javax.servlet.http.HttpServletRequest;
import ?javax.servlet.http.HttpServletResponse;
import ?java.util.List;
import ?org.apache.commons.fileupload.RequestContext;
import ?org.apache.commons.fileupload.servlet.ServletRequestContext;
import ?org.apache.commons.fileupload.servlet.ServletFileUpload;
import ?org.apache.commons.fileupload.disk.DiskFileItemFactory;
import ?org.apache.commons.fileupload.FileItem;
public ? class ?UploadServlet? extends ?HttpServlet?{
???? /**
?????*?Constructor?of?the?object.
????? */
???? public ?UploadServlet()?{
???????? super ();
????}
???? /**
?????*?Destruction?of?the?servlet.
????? */
???? public ? void ?destroy()?{
???????? super .destroy();
????}
???? public ? void ?doGet(HttpServletRequest?request,?HttpServletResponse?response)
???????????? throws ?ServletException,?IOException?{
????}
???? /**
?????*?上傳文件
?????*?
?????*? @param ?request
?????*? @param ?response
?????*? @throws ?ServletException
?????*? @throws ?IOException
????? */
???? public ? void ?doPost(HttpServletRequest?request,?HttpServletResponse?response)
???????????? throws ?ServletException,?IOException?{
????????response.setContentType( " text/html " );
????????response.setCharacterEncoding( " gbk " );
????????PrintWriter?out? = ?response.getWriter();
????????out.println( " <html> " );
????????out.println( " ??<head><title>提示</title></head> " );
????????out.println( " ??<body> " );
???????? // ?不用獲取?URL?對象也行,直接用?getServletContext().getRealPath("/")?代替。
????????URL?url? = ?getServletContext().getResource( " / " );
???????? // ?從?HTTP?servlet?獲取?fileupload?組件需要的內容
????????RequestContext?requestContext? = ? new ?ServletRequestContext(request);
???????? // ?判斷是否包含?multipart?內容
???????? if ?(ServletFileUpload.isMultipartContent(requestContext))?{
???????????? // ?創建基于磁盤的文件工廠
????????????DiskFileItemFactory?factory? = ? new ?DiskFileItemFactory();
???????????? // ?設置直接存儲文件的極限大小,一旦超過則寫入臨時文件以節約內存。默認為?1024?字節
????????????factory.setSizeThreshold( 1024 ? * ? 1024 );
???????????? // ?創建上傳處理器,可以處理從單個?HTML?上傳的多個上傳文件。
????????????ServletFileUpload?upload? = ? new ?ServletFileUpload(factory);
???????????? // ?最大允許上傳的文件大小
????????????upload.setSizeMax( 1024 ? * ? 1024 );
???????????? // ?處理上傳
????????????List?items? = ? null ;
???????????? try ?{
????????????????items? = ?upload.parseRequest(requestContext);
???????????????? // ?由于提交了表單字段信息,需要進行循環區分。
???????????????? for ?( int ?i? = ? 0 ;?i? < ?items.size();?i ++ )?{
????????????????????FileItem?fi? = ?(FileItem)?items.get(i);
???????????????????? // ?如果不是表單內容,取出?multipart。
???????????????????? if ?( ! fi.isFormField())?{
???????????????????????? // ?上傳文件路徑和文件、擴展名。
????????????????????????String?sourcePath? = ?fi.getName();
????????????????????????String[]?sourcePaths? = ?sourcePath.split( " \\\\ " );
???????????????????????? // ?獲取真實文件名
????????????????????????String?fileName? = ?sourcePaths[sourcePaths.length? - ? 1 ];
???????????????????????? // ?創建一個待寫文件
????????????????????????File?uploadedFile? = ? new ?File( new ?URI(url.toString() + fileName));
???????????????????????? // ?寫入
????????????????????????fi.write(uploadedFile);
????????????????????????out.println(fileName + " 上傳成功。 " );
????????????????????}
????????????????}
????????????}? catch ?(Exception?e)?{
????????????????out.println( " 上傳失敗,請檢查上傳文件大小是否超過1兆,并保證在上傳時該文件沒有被其他程序占用。 " );
????????????????out.println( " <br>原因: " + e.toString());
????????????????e.printStackTrace();
????????????}
????????}
????????out.println( " ??</body> " );
????????out.println( " </html> " );
????????out.flush();
????????out.close();
????}
???? /**
?????*?Initialization?of?the?servlet.
?????*?
?????*? @throws ?ServletException
????? */
???? public ? void ?init()? throws ?ServletException?{
????}
}
import ?java.io.PrintWriter;
import ?java.io.File;
import ?java.net.URI;
import ?java.net.URL;
import ?javax.servlet.ServletException;
import ?javax.servlet.http.HttpServlet;
import ?javax.servlet.http.HttpServletRequest;
import ?javax.servlet.http.HttpServletResponse;
import ?java.util.List;
import ?org.apache.commons.fileupload.RequestContext;
import ?org.apache.commons.fileupload.servlet.ServletRequestContext;
import ?org.apache.commons.fileupload.servlet.ServletFileUpload;
import ?org.apache.commons.fileupload.disk.DiskFileItemFactory;
import ?org.apache.commons.fileupload.FileItem;
public ? class ?UploadServlet? extends ?HttpServlet?{
???? /**
?????*?Constructor?of?the?object.
????? */
???? public ?UploadServlet()?{
???????? super ();
????}
???? /**
?????*?Destruction?of?the?servlet.
????? */
???? public ? void ?destroy()?{
???????? super .destroy();
????}
???? public ? void ?doGet(HttpServletRequest?request,?HttpServletResponse?response)
???????????? throws ?ServletException,?IOException?{
????}
???? /**
?????*?上傳文件
?????*?
?????*? @param ?request
?????*? @param ?response
?????*? @throws ?ServletException
?????*? @throws ?IOException
????? */
???? public ? void ?doPost(HttpServletRequest?request,?HttpServletResponse?response)
???????????? throws ?ServletException,?IOException?{
????????response.setContentType( " text/html " );
????????response.setCharacterEncoding( " gbk " );
????????PrintWriter?out? = ?response.getWriter();
????????out.println( " <html> " );
????????out.println( " ??<head><title>提示</title></head> " );
????????out.println( " ??<body> " );
???????? // ?不用獲取?URL?對象也行,直接用?getServletContext().getRealPath("/")?代替。
????????URL?url? = ?getServletContext().getResource( " / " );
???????? // ?從?HTTP?servlet?獲取?fileupload?組件需要的內容
????????RequestContext?requestContext? = ? new ?ServletRequestContext(request);
???????? // ?判斷是否包含?multipart?內容
???????? if ?(ServletFileUpload.isMultipartContent(requestContext))?{
???????????? // ?創建基于磁盤的文件工廠
????????????DiskFileItemFactory?factory? = ? new ?DiskFileItemFactory();
???????????? // ?設置直接存儲文件的極限大小,一旦超過則寫入臨時文件以節約內存。默認為?1024?字節
????????????factory.setSizeThreshold( 1024 ? * ? 1024 );
???????????? // ?創建上傳處理器,可以處理從單個?HTML?上傳的多個上傳文件。
????????????ServletFileUpload?upload? = ? new ?ServletFileUpload(factory);
???????????? // ?最大允許上傳的文件大小
????????????upload.setSizeMax( 1024 ? * ? 1024 );
???????????? // ?處理上傳
????????????List?items? = ? null ;
???????????? try ?{
????????????????items? = ?upload.parseRequest(requestContext);
???????????????? // ?由于提交了表單字段信息,需要進行循環區分。
???????????????? for ?( int ?i? = ? 0 ;?i? < ?items.size();?i ++ )?{
????????????????????FileItem?fi? = ?(FileItem)?items.get(i);
???????????????????? // ?如果不是表單內容,取出?multipart。
???????????????????? if ?( ! fi.isFormField())?{
???????????????????????? // ?上傳文件路徑和文件、擴展名。
????????????????????????String?sourcePath? = ?fi.getName();
????????????????????????String[]?sourcePaths? = ?sourcePath.split( " \\\\ " );
???????????????????????? // ?獲取真實文件名
????????????????????????String?fileName? = ?sourcePaths[sourcePaths.length? - ? 1 ];
???????????????????????? // ?創建一個待寫文件
????????????????????????File?uploadedFile? = ? new ?File( new ?URI(url.toString() + fileName));
???????????????????????? // ?寫入
????????????????????????fi.write(uploadedFile);
????????????????????????out.println(fileName + " 上傳成功。 " );
????????????????????}
????????????????}
????????????}? catch ?(Exception?e)?{
????????????????out.println( " 上傳失敗,請檢查上傳文件大小是否超過1兆,并保證在上傳時該文件沒有被其他程序占用。 " );
????????????????out.println( " <br>原因: " + e.toString());
????????????????e.printStackTrace();
????????????}
????????}
????????out.println( " ??</body> " );
????????out.println( " </html> " );
????????out.flush();
????????out.close();
????}
???? /**
?????*?Initialization?of?the?servlet.
?????*?
?????*? @throws ?ServletException
????? */
???? public ? void ?init()? throws ?ServletException?{
????}
}
上面的程序示范了如何上傳文件到服務器,本文的主要目的不光是上傳,還要進行 Excel 解析,抽取有用的內容。開源的 Excel 解析器很多,在此我選擇了 JExcelApi,可以在 http://jexcelapi.sourceforge.net 找到,據說是韓國人開發的,最新版本是 2.6.2。為什么沒有選 POI,原因也是因為它 N 久沒有更新了。我總是喜歡最新的東東,比如 Adobe 的 PDF Reader,硬是下載了 8.0,結果感覺還沒有 6.0 好用。:(
以下程序修改直上傳,做了部分調整,取消了文件儲存,直接通過讀取輸入流進行解析,并假設約定的 Excel 文件有五列 N 行,第一行為標題信息。
import
?java.io.IOException;
import ?java.io.PrintWriter;
import ?javax.servlet.ServletException;
import ?javax.servlet.http.HttpServlet;
import ?javax.servlet.http.HttpServletRequest;
import ?javax.servlet.http.HttpServletResponse;
import ?java.util.List;
import ?org.apache.commons.fileupload.RequestContext;
import ?org.apache.commons.fileupload.servlet.ServletRequestContext;
import ?org.apache.commons.fileupload.servlet.ServletFileUpload;
import ?org.apache.commons.fileupload.disk.DiskFileItemFactory;
import ?org.apache.commons.fileupload.FileItem;
import ?jxl.Workbook;
import ?jxl.Sheet;
import ?jxl.Cell;
public ? class ?UploadServlet? extends ?HttpServlet?{
????????
???? /**
?????*?Constructor?of?the?object.
????? */
???? public ?UploadServlet()?{
???????? super ();
????}
???? /**
?????*?Destruction?of?the?servlet.
????? */
???? public ? void ?destroy()?{
???????? super .destroy();
????}
???? public ? void ?doGet(HttpServletRequest?request,?HttpServletResponse?response)
???????????? throws ?ServletException,?IOException?{
????}
???? /**
?????*?上傳文件
?????*?
?????*? @param ?request
?????*? @param ?response
?????*? @throws ?ServletException
?????*? @throws ?IOException
????? */
???? public ? void ?doPost(HttpServletRequest?request,?HttpServletResponse?response)
???????????? throws ?ServletException,?IOException?{
????????response.setContentType( " text/html " );
????????response.setCharacterEncoding( " gbk " );
????????PrintWriter?out? = ?response.getWriter();
????????out.println( " <html> " );
????????out.println( " ??<head><title>提示</title></head> " );
????????out.println( " ??<body> " );
???????? // ?聲明文件域
????????FileItem?fileItem? = ? null ;
???????? // ?從?HTTP?servlet?獲取?fileupload?組件需要的內容
????????RequestContext?requestContext? = ? new ?ServletRequestContext(request);
???????? // ?判斷是否包含?multipart?內容,如果不包含,則不進行任何處理。
???????? if ?(ServletFileUpload.isMultipartContent(requestContext))?{
???????????? // ?創建基于磁盤的文件工廠
????????????DiskFileItemFactory?factory? = ? new ?DiskFileItemFactory();
???????????? // ?設置直接存儲文件的極限大小,一旦超過則寫入臨時文件以節約內存。默認為?1024?字節
????????????factory.setSizeThreshold( 1024 ? * ? 1024 );
???????????? // ?創建上傳處理器,可以處理從單個?HTML?上傳的多個上傳文件。
????????????ServletFileUpload?upload? = ? new ?ServletFileUpload(factory);
???????????? // ?最大允許上傳的文件大小
????????????upload.setSizeMax( 1024 ? * ? 1024 );
???????????? try ?{
???????????????? // ?處理上傳
????????????????List?items? = ? null ;
????????????????items? = ?upload.parseRequest(requestContext);
???????????????? // ?由于提交了表單字段信息,需要進行循環區分。
???????????????? for ?( int ?i? = ? 0 ;?i? < ?items.size();?i ++ )?{
????????????????????FileItem?fi? = ?(FileItem)?items.get(i);
???????????????????? // ?如果不是表單內容,取出?multipart。
???????????????????? if ?( ! fi.isFormField())?{
????????????????????????fileItem? = ?fi;
???????????????????????? // 一次只上傳單個文件
???????????????????????? break ;
????????????????????}
????????????????}
????????????????out.println(parseExcel(fileItem));
????????????}? catch ?(Exception?e)?{
????????????????out.println( " 上傳失敗!請檢查上傳的文件是否為excel格式、信息是否完整完整、且大小是否超過1兆。 " );
????????????????out.println( " <br>原因: " + e.toString());
????????????????e.printStackTrace();
????????????}
????????}
????????out.println( " ??</body> " );
????????out.println( " </html> " );
????????out.flush();
????????out.close();
????}
???? /**
?????*?分析excel文件
?????*?
?????*? @param ?FileItem?fi?文件域
?????*? @return ?String
?????*? @throws ?Exception
????? */
???? private ?String?parseExcel(FileItem?fi)? throws ?Exception{
???????? // ?聲明?Workbook
????????Workbook?workbook? = ? null ;
???????? try {
????????????workbook? = ?Workbook.getWorkbook(fi.getInputStream());
????????????Sheet?sheet? = ?workbook.getSheet( 0 );
???????????? // 總行數
???????????? int ?count? = ?sheet.getRows();
???????????? // 取出標題
??????????????String?a1? = ?sheet.getCell( 0 , 0 ).getContents();
??????????????String?a2? = ?sheet.getCell( 1 , 0 ).getContents();
??????????????String?a3? = ?sheet.getCell( 2 , 0 ).getContents();
??????????????String?a4? = ?sheet.getCell( 3 , 0 ).getContents();
??????????????String?a5? = ?sheet.getCell( 4 , 0 ).getContents();
???????????? // 取出內容
???????????? for ( int ?i? = ? 1 ;i? < ?count;i ++ ){
????????????????Cell[]?cells? = ?sheet.getRow(i);
????????????????System.out.println(cells[ 0 ].getContents()
???????????????????????? + cells[ 1 ].getContents() + cells[ 2 ].getContents()
???????????????????????? + cells[ 3 ].getContents() + cells[ 4 ].getContents());
????????????}
???????????? return ? " 上傳成功。 " ;????????????
????????} catch (Exception?e){
???????????? throw ?e;
????????} finally {
???????????? if (workbook != null ){
????????????????workbook.close();
????????????}
????????}
????}
????
???? /**
?????*?Initialization?of?the?servlet.
?????*?
?????*? @throws ?ServletException
????? */
???? public ? void ?init()? throws ?ServletException?{
????}
}
import ?java.io.PrintWriter;
import ?javax.servlet.ServletException;
import ?javax.servlet.http.HttpServlet;
import ?javax.servlet.http.HttpServletRequest;
import ?javax.servlet.http.HttpServletResponse;
import ?java.util.List;
import ?org.apache.commons.fileupload.RequestContext;
import ?org.apache.commons.fileupload.servlet.ServletRequestContext;
import ?org.apache.commons.fileupload.servlet.ServletFileUpload;
import ?org.apache.commons.fileupload.disk.DiskFileItemFactory;
import ?org.apache.commons.fileupload.FileItem;
import ?jxl.Workbook;
import ?jxl.Sheet;
import ?jxl.Cell;
public ? class ?UploadServlet? extends ?HttpServlet?{
????????
???? /**
?????*?Constructor?of?the?object.
????? */
???? public ?UploadServlet()?{
???????? super ();
????}
???? /**
?????*?Destruction?of?the?servlet.
????? */
???? public ? void ?destroy()?{
???????? super .destroy();
????}
???? public ? void ?doGet(HttpServletRequest?request,?HttpServletResponse?response)
???????????? throws ?ServletException,?IOException?{
????}
???? /**
?????*?上傳文件
?????*?
?????*? @param ?request
?????*? @param ?response
?????*? @throws ?ServletException
?????*? @throws ?IOException
????? */
???? public ? void ?doPost(HttpServletRequest?request,?HttpServletResponse?response)
???????????? throws ?ServletException,?IOException?{
????????response.setContentType( " text/html " );
????????response.setCharacterEncoding( " gbk " );
????????PrintWriter?out? = ?response.getWriter();
????????out.println( " <html> " );
????????out.println( " ??<head><title>提示</title></head> " );
????????out.println( " ??<body> " );
???????? // ?聲明文件域
????????FileItem?fileItem? = ? null ;
???????? // ?從?HTTP?servlet?獲取?fileupload?組件需要的內容
????????RequestContext?requestContext? = ? new ?ServletRequestContext(request);
???????? // ?判斷是否包含?multipart?內容,如果不包含,則不進行任何處理。
???????? if ?(ServletFileUpload.isMultipartContent(requestContext))?{
???????????? // ?創建基于磁盤的文件工廠
????????????DiskFileItemFactory?factory? = ? new ?DiskFileItemFactory();
???????????? // ?設置直接存儲文件的極限大小,一旦超過則寫入臨時文件以節約內存。默認為?1024?字節
????????????factory.setSizeThreshold( 1024 ? * ? 1024 );
???????????? // ?創建上傳處理器,可以處理從單個?HTML?上傳的多個上傳文件。
????????????ServletFileUpload?upload? = ? new ?ServletFileUpload(factory);
???????????? // ?最大允許上傳的文件大小
????????????upload.setSizeMax( 1024 ? * ? 1024 );
???????????? try ?{
???????????????? // ?處理上傳
????????????????List?items? = ? null ;
????????????????items? = ?upload.parseRequest(requestContext);
???????????????? // ?由于提交了表單字段信息,需要進行循環區分。
???????????????? for ?( int ?i? = ? 0 ;?i? < ?items.size();?i ++ )?{
????????????????????FileItem?fi? = ?(FileItem)?items.get(i);
???????????????????? // ?如果不是表單內容,取出?multipart。
???????????????????? if ?( ! fi.isFormField())?{
????????????????????????fileItem? = ?fi;
???????????????????????? // 一次只上傳單個文件
???????????????????????? break ;
????????????????????}
????????????????}
????????????????out.println(parseExcel(fileItem));
????????????}? catch ?(Exception?e)?{
????????????????out.println( " 上傳失敗!請檢查上傳的文件是否為excel格式、信息是否完整完整、且大小是否超過1兆。 " );
????????????????out.println( " <br>原因: " + e.toString());
????????????????e.printStackTrace();
????????????}
????????}
????????out.println( " ??</body> " );
????????out.println( " </html> " );
????????out.flush();
????????out.close();
????}
???? /**
?????*?分析excel文件
?????*?
?????*? @param ?FileItem?fi?文件域
?????*? @return ?String
?????*? @throws ?Exception
????? */
???? private ?String?parseExcel(FileItem?fi)? throws ?Exception{
???????? // ?聲明?Workbook
????????Workbook?workbook? = ? null ;
???????? try {
????????????workbook? = ?Workbook.getWorkbook(fi.getInputStream());
????????????Sheet?sheet? = ?workbook.getSheet( 0 );
???????????? // 總行數
???????????? int ?count? = ?sheet.getRows();
???????????? // 取出標題
??????????????String?a1? = ?sheet.getCell( 0 , 0 ).getContents();
??????????????String?a2? = ?sheet.getCell( 1 , 0 ).getContents();
??????????????String?a3? = ?sheet.getCell( 2 , 0 ).getContents();
??????????????String?a4? = ?sheet.getCell( 3 , 0 ).getContents();
??????????????String?a5? = ?sheet.getCell( 4 , 0 ).getContents();
???????????? // 取出內容
???????????? for ( int ?i? = ? 1 ;i? < ?count;i ++ ){
????????????????Cell[]?cells? = ?sheet.getRow(i);
????????????????System.out.println(cells[ 0 ].getContents()
???????????????????????? + cells[ 1 ].getContents() + cells[ 2 ].getContents()
???????????????????????? + cells[ 3 ].getContents() + cells[ 4 ].getContents());
????????????}
???????????? return ? " 上傳成功。 " ;????????????
????????} catch (Exception?e){
???????????? throw ?e;
????????} finally {
???????????? if (workbook != null ){
????????????????workbook.close();
????????????}
????????}
????}
????
???? /**
?????*?Initialization?of?the?servlet.
?????*?
?????*? @throws ?ServletException
????? */
???? public ? void ?init()? throws ?ServletException?{
????}
}
JExcelApi 用起來很簡單,而且還可以根據 Excel 中數據類型轉換成 Java 數據類型,比如 int、double,具體信息可以參考它的開發指南。當然,本范例還提供現構造 Excel 然后下載的方法,如果以后遇到,一定繼續完善。
------------------------------------------------------------------------------------------------
關于生成 excel 和下載,一月份的文章還留了個尾巴,今天把它補充上去。2007-04-22 by rosen jiang
代碼如下,放在 servlet 中,io 異常我沒捕獲,直接由 get or post 方法拋出,當然,如果更嚴謹點可以放在 finally 里關閉。
????????//設置輸出格式和頭信息
????????response.setContentType("application/x-msdownload;charset=GBK");
????????String?filename?=?new?String("供應商報價清單.xls".getBytes("GBK"),"ISO_8859_1");
????????response.setHeader("Content-Disposition","attachment;filename="+filename);
????????//虛擬數據
????????String?materialName?=?"馬桶";???????//材料名
????????String?size?=?"200×300";???????????//規格
????????String?unit?=?"臺";????????????????//單位
????????String?qty?=?"2";??????????????????//數量
????????String?band?=?"不知道牌子";??????????//材料品牌
????????String?company?=?"成都某廠";?????????//廠家名
????????String?memo?=?"質量可靠";????????????//備注
????????String?price?=?"20.30";????????????//價格
????????String?repDate?=?"2007-04-11";?????//報價時間
????????List<String[]>?list?=?new?ArrayList<String[]>();
????????for(int?i?=?10;?i?>?0;?i--){
????????????String[]?outPut?=?{materialName,size,unit,qty+i,band,company,memo,price,repDate};
????????????list.add(outPut);
????????}
????????//輸出流
????????ByteArrayOutputStream?baos?=?new?ByteArrayOutputStream();
????????//構造工作區
????????WritableWorkbook?workbook?=?Workbook.createWorkbook(baos);
????????//構造?sheet
????????WritableSheet?sheet?=?workbook.createSheet("報價清單",?0);
????????//構造粗標題字體
????????WritableFont?blodFont?=?new?WritableFont(WritableFont.TAHOMA,10,WritableFont.BOLD,?false);
????????WritableCellFormat?blodFormat?=?new?WritableCellFormat?(blodFont);
????????Label?label?=?null;
????????try?{
????????????//標題行
????????????label?=?new?Label(0,?0,?"材料名",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(1,?0,?"規格",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(2,?0,?"單位",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(3,?0,?"數量",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(4,?0,?"材料品牌",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(5,?0,?"廠家名",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(6,?0,?"備注",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(7,?0,?"價格",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(8,?0,?"報價時間",?blodFormat);
????????????sheet.addCell(label);
????????????//輸出業務數據
????????????for(int?i?=?1;?i?<=?list.size();?i++){
????????????????String[]?outPut?=?list.get(i-1);
????????????????label?=?new?Label(0,?i,?outPut[0]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(1,?i,?outPut[1]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(2,?i,?outPut[2]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(3,?i,?outPut[3]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(4,?i,?outPut[4]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(5,?i,?outPut[5]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(6,?i,?outPut[6]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(7,?i,?outPut[7]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(8,?i,?repDate);
????????????????sheet.addCell(label);
????????????}
????????????//寫入文件
????????????workbook.write();
????????????workbook.close();
????????????//向瀏覽器返回文件流
????????????OutputStream?os?=?response.getOutputStream();
????????????os.write(baos.toByteArray());
????????????os.flush();
????????????os.close();
????????????baos.close();
????????}?catch?(RowsExceededException?e)?{
????????????e.printStackTrace();
????????}?catch?(WriteException?e)?{
????????????e.printStackTrace();
????????}
????}
????????response.setContentType("application/x-msdownload;charset=GBK");
????????String?filename?=?new?String("供應商報價清單.xls".getBytes("GBK"),"ISO_8859_1");
????????response.setHeader("Content-Disposition","attachment;filename="+filename);
????????//虛擬數據
????????String?materialName?=?"馬桶";???????//材料名
????????String?size?=?"200×300";???????????//規格
????????String?unit?=?"臺";????????????????//單位
????????String?qty?=?"2";??????????????????//數量
????????String?band?=?"不知道牌子";??????????//材料品牌
????????String?company?=?"成都某廠";?????????//廠家名
????????String?memo?=?"質量可靠";????????????//備注
????????String?price?=?"20.30";????????????//價格
????????String?repDate?=?"2007-04-11";?????//報價時間
????????List<String[]>?list?=?new?ArrayList<String[]>();
????????for(int?i?=?10;?i?>?0;?i--){
????????????String[]?outPut?=?{materialName,size,unit,qty+i,band,company,memo,price,repDate};
????????????list.add(outPut);
????????}
????????//輸出流
????????ByteArrayOutputStream?baos?=?new?ByteArrayOutputStream();
????????//構造工作區
????????WritableWorkbook?workbook?=?Workbook.createWorkbook(baos);
????????//構造?sheet
????????WritableSheet?sheet?=?workbook.createSheet("報價清單",?0);
????????//構造粗標題字體
????????WritableFont?blodFont?=?new?WritableFont(WritableFont.TAHOMA,10,WritableFont.BOLD,?false);
????????WritableCellFormat?blodFormat?=?new?WritableCellFormat?(blodFont);
????????Label?label?=?null;
????????try?{
????????????//標題行
????????????label?=?new?Label(0,?0,?"材料名",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(1,?0,?"規格",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(2,?0,?"單位",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(3,?0,?"數量",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(4,?0,?"材料品牌",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(5,?0,?"廠家名",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(6,?0,?"備注",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(7,?0,?"價格",?blodFormat);
????????????sheet.addCell(label);
????????????label?=?new?Label(8,?0,?"報價時間",?blodFormat);
????????????sheet.addCell(label);
????????????//輸出業務數據
????????????for(int?i?=?1;?i?<=?list.size();?i++){
????????????????String[]?outPut?=?list.get(i-1);
????????????????label?=?new?Label(0,?i,?outPut[0]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(1,?i,?outPut[1]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(2,?i,?outPut[2]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(3,?i,?outPut[3]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(4,?i,?outPut[4]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(5,?i,?outPut[5]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(6,?i,?outPut[6]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(7,?i,?outPut[7]);
????????????????sheet.addCell(label);
????????????????label?=?new?Label(8,?i,?repDate);
????????????????sheet.addCell(label);
????????????}
????????????//寫入文件
????????????workbook.write();
????????????workbook.close();
????????????//向瀏覽器返回文件流
????????????OutputStream?os?=?response.getOutputStream();
????????????os.write(baos.toByteArray());
????????????os.flush();
????????????os.close();
????????????baos.close();
????????}?catch?(RowsExceededException?e)?{
????????????e.printStackTrace();
????????}?catch?(WriteException?e)?{
????????????e.printStackTrace();
????????}
????}
生成 excel 的樣子是這樣的:

請注意!引用、轉貼本文應注明原作者:Rosen Jiang 以及出處:http://www.aygfsteel.com/rosen