设为首页 收藏本站
查看: 798|回复: 0

[经验分享] 使用Apache FileUpload 上传以及 JExcelApi 生成Excel文件

[复制链接]

尚未签到

发表于 2017-1-11 07:09:07 | 显示全部楼层 |阅读模式
<!-- Feedsky FEED发布代码开始 -->欢迎点击此处订阅本Blog<!-- FEED自动发现标记开始 --><link title="RSS 2.0" type="application/rss+xml" href="http://feed.feedsky.com/softwave" rel="alternate"><!-- FEED自动发现标记结束 --> DSC0000.gif

<!--Google 468*60横幅广告开始--><script type="text/javascript"><!--google_ad_client = "pub-7343546549496470";google_ad_width = 468;google_ad_height = 60;google_ad_format = "468x60_as";google_ad_type = "image";//2007-07-26: CSDNgoogle_ad_channel = "6063905817";google_color_border = "6699CC";google_color_bg = "E6E6E6";google_color_link = "FFFFFF";google_color_text = "333333";google_color_url = "AECCEB";google_ui_features = "rc:6";//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><!--Google 468*60横幅广告结束-->

本文转载自:http://www.blogjava.net/rosen

  最近遇到点读取 Excel 数据的问题,于是花了点时间找开源工具。
要解析 Excel,首当其冲的是上传文件,以前在项目里我们用 SmartUpload 进行上传,不过这个项目似乎已经停止开发了,于是在这里我使用 Apache Commons FileUpload,可以在 http://jakarta.apache.org/commons/fileupload 找到。目前该项目的最新版本是 1.1.1,网上有大量的范例程序,不过后来用的时候发现大部分方法在新版本中都不推荐使用了,于是好好读了一回 API 和官方范例。
  先来看看如何上传文件,Servlet 很简单,在这里我限制了最大上传量为 1M,且直接读进内存中,不进行磁盘临时文件缓存。
importjava.io.IOException;
importjava.io.PrintWriter;
importjava.io.File;
importjava.net.URI;
importjava.net.URL;

importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

importjava.util.List;

importorg.apache.commons.fileupload.RequestContext;
importorg.apache.commons.fileupload.servlet.ServletRequestContext;
importorg.apache.commons.fileupload.servlet.ServletFileUpload;
importorg.apache.commons.fileupload.disk.DiskFileItemFactory;
importorg.apache.commons.fileupload.FileItem;

publicclassUploadServletextendsHttpServlet{

/**
*Constructoroftheobject.
*/
publicUploadServlet(){
super();
}

/**
*Destructionoftheservlet.
*/
publicvoiddestroy(){
super.destroy();
}

publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
}

/**
*上传文件
*
*
@paramrequest
*
@paramresponse
*
@throwsServletException
*
@throwsIOException
*/
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
response.setContentType(
"text/html");
response.setCharacterEncoding(
"gbk");
PrintWriterout
=response.getWriter();
out.println(
"<html>");
out.println(
"<head><title>提示</title></head>");
out.println(
"<body>");
//不用获取URL对象也行,直接用getServletContext().getRealPath("/")代替。
URLurl=getServletContext().getResource("/");
//从HTTPservlet获取fileupload组件需要的内容
RequestContextrequestContext=newServletRequestContext(request);
//判断是否包含multipart内容
if(ServletFileUpload.isMultipartContent(requestContext)){
//创建基于磁盘的文件工厂
DiskFileItemFactoryfactory=newDiskFileItemFactory();
//设置直接存储文件的极限大小,一旦超过则写入临时文件以节约内存。默认为1024字节
factory.setSizeThreshold(1024*1024);
//创建上传处理器,可以处理从单个HTML上传的多个上传文件。
ServletFileUploadupload=newServletFileUpload(factory);
//最大允许上传的文件大小
upload.setSizeMax(1024*1024);
//处理上传
Listitems=null;
try{
items
=upload.parseRequest(requestContext);
//由于提交了表单字段信息,需要进行循环区分。
for(inti=0;i<items.size();i++){
FileItemfi
=(FileItem)items.get(i);
//如果不是表单内容,取出multipart。
if(!fi.isFormField()){
//上传文件路径和文件、扩展名。
StringsourcePath=fi.getName();
String[]sourcePaths
=sourcePath.split("////");
//获取真实文件名
StringfileName=sourcePaths[sourcePaths.length-1];
//创建一个待写文件
FileuploadedFile=newFile(newURI(url.toString()+fileName));
//写入
fi.write(uploadedFile);
out.println(fileName
+"上传成功。");
}
}
}
catch(Exceptione){
out.println(
"上传失败,请检查上传文件大小是否超过1兆,并保证在上传时该文件没有被其他程序占用。");
out.println(
"<br>原因:"+e.toString());
e.printStackTrace();
}
}
out.println(
"</body>");
out.println(
"</html>");
out.flush();
out.close();
}

/**
*Initializationoftheservlet.
*
*
@throwsServletException
*/
publicvoidinit()throwsServletException{
}
}

  
上面的程序示范了如何上传文件到服务器,本文的主要目的不光是上传,还要进行 Excel 解析,抽取有用的内容。开源的 Excel 解析器很多,在此我选择了 JExcelApi,可以在 http://jexcelapi.sourceforge.net 找到,据说是韩国人开发的,最新版本是 2.6.2。为什么没有选 POI,原因也是因为它 N 久没有更新了。我总是喜欢最新的东东,比如 Adobe 的 PDF Reader,硬是下载了 8.0,结果感觉还没有 6.0 好用。:(
  以下程序修改直上传,做了部分调整,取消了文件储存,直接通过读取输入流进行解析,并假设约定的 Excel 文件有五列 N 行,第一行为标题信息。
importjava.io.IOException;
importjava.io.PrintWriter;

importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

importjava.util.List;

importorg.apache.commons.fileupload.RequestContext;
importorg.apache.commons.fileupload.servlet.ServletRequestContext;
importorg.apache.commons.fileupload.servlet.ServletFileUpload;
importorg.apache.commons.fileupload.disk.DiskFileItemFactory;
importorg.apache.commons.fileupload.FileItem;

importjxl.Workbook;
importjxl.Sheet;
importjxl.Cell;

publicclassUploadServletextendsHttpServlet{

/**
*Constructoroftheobject.
*/
publicUploadServlet(){
super();
}

/**
*Destructionoftheservlet.
*/
publicvoiddestroy(){
super.destroy();
}

publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
}

/**
*上传文件
*
*
@paramrequest
*
@paramresponse
*
@throwsServletException
*
@throwsIOException
*/
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
response.setContentType(
"text/html");
response.setCharacterEncoding(
"gbk");
PrintWriterout
=response.getWriter();
out.println(
"<html>");
out.println(
"<head><title>提示</title></head>");
out.println(
"<body>");
//声明文件域
FileItemfileItem=null;
//从HTTPservlet获取fileupload组件需要的内容
RequestContextrequestContext=newServletRequestContext(request);
//判断是否包含multipart内容,如果不包含,则不进行任何处理。
if(ServletFileUpload.isMultipartContent(requestContext)){
//创建基于磁盘的文件工厂
DiskFileItemFactoryfactory=newDiskFileItemFactory();
//设置直接存储文件的极限大小,一旦超过则写入临时文件以节约内存。默认为1024字节
factory.setSizeThreshold(1024*1024);
//创建上传处理器,可以处理从单个HTML上传的多个上传文件。
ServletFileUploadupload=newServletFileUpload(factory);
//最大允许上传的文件大小
upload.setSizeMax(1024*1024);
try{
//处理上传
Listitems=null;
items
=upload.parseRequest(requestContext);
//由于提交了表单字段信息,需要进行循环区分。
for(inti=0;i<items.size();i++){
FileItemfi
=(FileItem)items.get(i);
//如果不是表单内容,取出multipart。
if(!fi.isFormField()){
fileItem
=fi;
//一次只上传单个文件
break;
}
}
out.println(parseExcel(fileItem));
}
catch(Exceptione){
out.println(
"上传失败!请检查上传的文件是否为excel格式、信息是否完整完整、且大小是否超过1兆。");
out.println(
"<br>原因:"+e.toString());
e.printStackTrace();
}
}
out.println(
"</body>");
out.println(
"</html>");
out.flush();
out.close();
}

/**
*分析excel文件
*
*
@paramFileItemfi文件域
*
@returnString
*
@throwsException
*/
privateStringparseExcel(FileItemfi)throwsException{
//声明Workbook
Workbookworkbook=null;
try{
workbook
=Workbook.getWorkbook(fi.getInputStream());
Sheetsheet
=workbook.getSheet(0);
//总行数
intcount=sheet.getRows();
//取出标题
Stringa1=sheet.getCell(0,0).getContents();
Stringa2
=sheet.getCell(1,0).getContents();
Stringa3
=sheet.getCell(2,0).getContents();
Stringa4
=sheet.getCell(3,0).getContents();
Stringa5
=sheet.getCell(4,0).getContents();
//取出内容
for(inti=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(Exceptione){
throwe;
}
finally{
if(workbook!=null){
workbook.close();
}
}
}

/**
*Initializationoftheservlet.
*
*
@throwsServletException
*/
publicvoidinit()throwsServletException{
}
}


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");
Stringfilename
=newString("供应商报价清单.xls".getBytes("GBK"),"ISO_8859_1");
response.setHeader(
"Content-Disposition","attachment;filename="+filename);

//虚拟数据
StringmaterialName="马桶";//材料名
Stringsize="200×300";//规格
Stringunit="";//单位
Stringqty="2";//数量
Stringband="不知道牌子";//材料品牌
Stringcompany="成都某厂";//厂家名
Stringmemo="质量可靠";//备注
Stringprice="20.30";//价格
StringrepDate="2007-04-11";//报价时间
List<String[]>list=newArrayList<String[]>();
for(inti=10;i>0;i--){
String[]outPut
={materialName,size,unit,qty+i,band,company,memo,price,repDate};
list.add(outPut);
}

//输出流
ByteArrayOutputStreambaos=newByteArrayOutputStream();
//构造工作区
WritableWorkbookworkbook=Workbook.createWorkbook(baos);
//构造sheet
WritableSheetsheet=workbook.createSheet("报价清单",0);
//构造粗标题字体
WritableFontblodFont=newWritableFont(WritableFont.TAHOMA,10,WritableFont.BOLD,false);
WritableCellFormatblodFormat
=newWritableCellFormat(blodFont);
Labellabel
=null;
try{
//标题行
label=newLabel(0,0,"材料名",blodFormat);
sheet.addCell(label);
label
=newLabel(1,0,"规格",blodFormat);
sheet.addCell(label);
label
=newLabel(2,0,"单位",blodFormat);
sheet.addCell(label);
label
=newLabel(3,0,"数量",blodFormat);
sheet.addCell(label);
label
=newLabel(4,0,"材料品牌",blodFormat);
sheet.addCell(label);
label
=newLabel(5,0,"厂家名",blodFormat);
sheet.addCell(label);
label
=newLabel(6,0,"备注",blodFormat);
sheet.addCell(label);
label
=newLabel(7,0,"价格",blodFormat);
sheet.addCell(label);
label
=newLabel(8,0,"报价时间",blodFormat);
sheet.addCell(label);
//输出业务数据
for(inti=1;i<=list.size();i++){
String[]outPut
=list.get(i-1);
label
=newLabel(0,i,outPut[0]);
sheet.addCell(label);
label
=newLabel(1,i,outPut[1]);
sheet.addCell(label);
label
=newLabel(2,i,outPut[2]);
sheet.addCell(label);
label
=newLabel(3,i,outPut[3]);
sheet.addCell(label);
label
=newLabel(4,i,outPut[4]);
sheet.addCell(label);
label
=newLabel(5,i,outPut[5]);
sheet.addCell(label);
label
=newLabel(6,i,outPut[6]);
sheet.addCell(label);
label
=newLabel(7,i,outPut[7]);
sheet.addCell(label);
label
=newLabel(8,i,repDate);
sheet.addCell(label);
}
//写入文件
workbook.write();
workbook.close();

//向浏览器返回文件流
OutputStreamos=response.getOutputStream();
os.write(baos.toByteArray());
os.flush();
os.close();
baos.close();
}
catch(RowsExceededExceptione){
e.printStackTrace();
}
catch(WriteExceptione){
e.printStackTrace();
}
}


生成 excel 的样子是这样的:
DSC0001.jpg

请注意!引用、转贴本文应注明原作者:Rosen Jiang 以及出处:http://www.blogjava.net/rosen


<!--新Google 468*60横幅广告开始--><script type="text/javascript"><!--google_ad_client = "pub-7343546549496470";/* 468x60, 创建于 08-8-6 */google_ad_slot = "7368701459";google_ad_width = 468;google_ad_height = 60;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><!--新Google 468*60横幅广告结束-->

<!--新Google 468x15 横链接单元开始--><script type="text/javascript"><!--google_ad_client = "pub-7343546549496470";/* 468x15 横链接单元 */google_ad_slot = "5785741422";google_ad_width = 468;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><!--新Google 468x15 横链接单元结束-->

<!-- Google Reader shared发布代码开始 --><script type="text/javascript" src="http://www.google.com/reader/ui/publisher.js"></script><script type="text/javascript" src="http://www.google.com/reader/public/javascript/user/00697638153916680411/state/com.google/broadcast?n=5&amp;callback=GRC_p(%7Bc%3A%22green%22%2Ct%3A%22%5Cu8FD9%5Cu4E9B%5Cu6587%5Cu7AE0%5Cu4E5F%5Cu503C%5Cu5F97%5Cu4E00%5Cu770B%22%2Cs%3A%22false%22%7D)%3Bnew%20GRC"></script><!-- Google Reader shared发布代码结束 -->

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-326648-1-1.html 上篇帖子: Apache POI (JAVA处理Office文档的类库) 下篇帖子: 质疑 apache和yaws的性能比较(必看)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表