在软件开发过程中难免需要批量上传与下载,生成报表保存也是常有之事,最近集团门户开发用到了Excel模版下载,Excel生成,圆满完成,对这一知识点进行整理,资源共享,有不足之处还望批评指正,文章结尾提供了所需jar包的下载,方便大伙使用,下面言归正传!

1.Excel的下载

1)Action中:

添加响应事件,通过getRealPath获得工程路径,与jsp中获得request.getContextPath()效果相同,fileName为要下载的文件名,经过拼接filePath是xls文件的绝对路径,调用工具类DownLoadUtil中的downLoadUtil方法;

 public ActionForward downLoadExcelModel(ActionMapping actionMapping,
ActionForm actionForm, HttpServletRequest request,
HttpServletResponse response) throws Exception {
String path = request.getSession().getServletContext().getRealPath(
"/resources");
String fileName = "成员模版.xls";
String filePath = path + "\\" + fileName;
DownLoadUtil.downLoadFile(filePath, response, fileName, "xls");
return null;
}

2)工具类DownLoadUtil中:

 public static boolean downLoadFile(String filePath,
HttpServletResponse response, String fileName, String fileType)
throws Exception {
File file = new File(filePath); //根据文件路径获得File文件
//设置文件类型(这样设置就不止是下Excel文件了,一举多得)
if("pdf".equals(fileType)){
response.setContentType("application/pdf;charset=GBK");
}else if("xls".equals(fileType)){
response.setContentType("application/msexcel;charset=GBK");
}else if("doc".equals(fileType)){
response.setContentType("application/msword;charset=GBK");
} //文件名
response.setHeader("Content-Disposition", "attachment;filename=\""
+ new String(fileName.getBytes(), "ISO8859-1") + "\"");
response.setContentLength((int) file.length());
byte[] buffer = new byte[4096];// 缓冲区
BufferedOutputStream output = null;
BufferedInputStream input = null;
try {
output = new BufferedOutputStream(response.getOutputStream());
input = new BufferedInputStream(new FileInputStream(file));
int n = -1; //遍历,开始下载
while ((n = input.read(buffer, 0, 4096)) > -1) {
output.write(buffer, 0, n);
}
output.flush(); //不可少
response.flushBuffer();//不可少
} catch (Exception e) {
//异常自己捕捉 } finally { //关闭流,不可少
if (input != null)
input.close();
if (output != null)
output.close();
} return false;
}

这样,就可以完成文件的下载,java程序将文件以流的形式,保存到客户本机!!

2、Excel的上传与解析(此处方面起见,ExcelN行两列,以为手机号,另一为短号)

对于数据批量上传,就涉及到文件的上传与数据的解析功能,此处运用了第三方jar包,方便快捷。对于文件上传,用到了commons-fileupload-1.1.1.jar与commons-io-1.1.jar,代码中并没有导入common-io包中的内容,而fielupload包的上传依赖于common-io,所以两者皆不可少;而对于Excel的解析,此处用到了jxl-2.6.jar。下面通过代码对各步骤进行解析。

1)jsp文件:

对于文件的上传,强烈推荐使用form表单,并设置enctype="multipart/form-data" method="post",action为处理文件的路径

 <form id="fileUpload" action="excel.do?method=exportMemberExcel" enctype="multipart/form-data" method="post">
<input id="excelFile" name="file" type="file"/>
<input type="button" value="提交" onclick="submitExcel()"/>
</form>

2)js文件:

通过js文件对上传的文件进行初识的格式验证,判断是否为空以及格式是否正确,正确的话提交表单,由后台对上传的文件处理,此处用的是jQuery,需要导入jquery-***.js,此处使用的是jquery-1.4.2.min.js(最后提供下载地址)。

function submitExcel(){
var excelFile = $("#excelFile").val();
if(excelFile=='') {alert("请选择需上传的文件!");return false;}
if(excelFile.indexOf('.xls')==-1){alert("文件格式不正确,请选择正确的Excel文件(后缀名.xls)!");return false;}
$("#fileUpload").submit();
}

3)Action中:

使用common-fileupload包中的类FileItemFactory,ServletFileUpload对请求进行处理,如果是文件,用工具累ExcelUtil处理,不是文件,此处未处理,不过以后开发可以根据需要处理,此处不纍述。(因为如果Excel中如果存在错误记录,还需供用户下载,所以若有错误信息,暂保存在session中,待用户下载后可清空此session)。

 public ActionForward exportMemberExcel(ActionMapping actionMapping,
ActionForm actionForm, HttpServletRequest request,
HttpServletResponse response) throws Exception {
int maxPostSize = 1000 * 1024 * 1024;
FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
servletFileUpload.setSizeMax(maxPostSize); try {
List fileItems = servletFileUpload.parseRequest(request);
Iterator iter = fileItems.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (!item.isFormField()) {// 是文件
Map map = ExcelUtil.excel2PhoneList(item.getInputStream()); String[][] error = (String[][]) map.get("error"); if (error.length != 0) {
//如果存在错误,存入内存,供用户保存
request.setAttribute("errorFlag", "ture");
request.getSession().setAttribute("exportMap", map);
} else {
request.setAttribute("errorFalg", "false");
// 获取正确的值填写json
String phoneJson = JsonUtil
.phoneArray2Json((String[][]) map
.get("current"));
request.setAttribute("phoneJson", phoneJson);
}
} else { //不是文件,此处不处理,对于text,password等文本框可在此处理
logger.error("wrong file");
}
}
} catch (Exception e) {
logger.error("invoke fileUpload error.", e);
}
return actionMapping.findForward("queryAccounts");
}

4、工具类ExcelUtil

主要借助jxl包对Excel文件进行解析,获取正确信息以及错误信息,供用户取舍。

 public static Map excel2PhoneList(InputStream inputStream) throws Exception {
Map map = new HashMap();
Workbook workbook = Workbook.getWorkbook(inputStream); //处理输入流
Sheet sheet = workbook.getSheet(0);// 获取第一个sheet
int rows = sheet.getRows(); //获取总行号
String[][] curArr = new String[rows][2]; //存放正确心细
String[][] errorArr = new String[rows * 2][4]; //存放错误信息
int curLines = 0;
int errorLines = 0;
for (int i = 1; i < rows; i++) {// 遍历行获得每行信息 String phone = sheet.getCell(0, i).getContents();// 获得第i行第1列信息 String shortNum = sheet.getCell(1, i).getContents();// 短号
StringBuffer errorMsg = new StringBuffer();
if (!isRowEmpty(sheet, i)) { //此行不为空
//对此行信息进行正误判断
}
}// 行 //正误信息存入map,保存
map.put("current", current);
map.put("error", error);
return map;
} private static boolean isRowEmpty(Sheet sheet, int i) {
String phone = sheet.getCell(0, i).getContents();// 集团编号
String shortNum = sheet.getCell(1, i).getContents();// 集团名称
if (isEmpty(phone) && isEmpty(shortNum))
return true;
return false;
}

返回值由Action处理,此处为止,Excel的解析就完成了!

3 生成Excel

上文中说到如果存在错误信息,可供用户下载,错误信息存在Session中,下载就需要利用Session中的数据生成Excel文档,供用户保存。

1)Action中:

Action从Session中获取保存的对象,调用工具类保存,然后删除Session中的内容.

 public ActionForward downErrorExcel(ActionMapping actionMapping,
ActionForm actionForm, HttpServletRequest request,
HttpServletResponse response) throws Exception {
Map map = (Map) request.getSession().getAttribute("exportMap");
ExcelUtil.createExcel(response, map);
request.getSession.removeAttribure("exportMap");
return null;
}

2)工具类ExcelUtil中:

 public static boolean createExcel(HttpServletResponse response, Map map) {
WritableWorkbook wbook = null;
WritableSheet sheet = null;
OutputStream os = null;
try {
response.reset(); //生成文件名
response.setHeader("Content-disposition", "attachment; filename="
+ new String("错误信息".getBytes("GB2312"), "ISO8859-1")
+ ".xls");
response.setContentType("application/msexcel");
os = response.getOutputStream();
wbook = Workbook.createWorkbook(os);
sheet = wbook.createSheet("信息", 0); int row = 0; //填写表头
setSheetTitle(sheet, row); //遍历map,填充数据
setSheetData(sheet, map, row); wbook.write();
os.flush();
} catch (Exception e) {
//自己处理
}finally {
try {//切记,此处一定要关闭流,否则你会下载一个空文件
if (wbook != null)
wbook.close();
if (os != null)
os.close();
} catch (IOException e) {
e.printStackTrace();
} catch (WriteException e) {
e.printStackTrace();
}
}
return false;
} private static void setSheetTitle(WritableSheet sheet, int row)
throws RowsExceededException, WriteException {
// 设置excel标题格式
WritableFont wfont = new WritableFont(WritableFont.ARIAL, 12,
WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE,
Colour.BLACK);
WritableCellFormat wcfFC = new WritableCellFormat(wfont); //设置每一列宽度
sheet.setColumnView(0,13);
sheet.setColumnView(1,13);
sheet.setColumnView(2,13);
sheet.setColumnView(3,50); //填写第一行提示信息 sheet.addCell(new Label(0, row, "手机号码", wcfFC));
sheet.addCell(new Label(1, row, "短号", wcfFC));
sheet.addCell(new Label(2, row, "原错误行号", wcfFC));
sheet.addCell(new Label(3, row, "错误原因", wcfFC));
} private static void setSheetData(WritableSheet sheet, Map map, int row)
throws RowsExceededException, WriteException {
WritableFont wfont = new WritableFont(WritableFont.ARIAL, 10,
WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE,
Colour.RED);
WritableCellFormat wcfFC = new WritableCellFormat(wfont); //从map中获取数据
String[][] error = (String[][]) map.get("error"); //遍历并填充
for (int i = 0; i < error.length; i++) {
row++;
sheet.addCell(new Label(0, row, error[i][0]));
sheet.addCell(new Label(1, row, error[i][1]));
sheet.addCell(new Label(2, row, error[i][2]));
sheet.addCell(new Label(3, row, error[i][3],wcfFC));
}
}

Excel文件生成之后,由response传给客户,客户选择路径,就可以下载了,至此,完成了Excel文件下载、解析、和生成的工作,大功一件,希望有所启发。

另外,补充一下,火狐fireFox在上传文件时,服务器端并不能获取客户端存取文件的绝对路径,而只是一个文件名,ie8以及低版本上传文件时,服务器可以获得绝对路径,这是火狐的安全机制决定的,所以试图根据上传的文件路径,对文件修改然后保存到原文件,这种是不可取的,一者是因为火狐下获取不到文件路径,二者即使服务器在ie下获得了文件的绝对路径,在创建并修改文件时也只是生成在服务器端,并不能修改客户端的文件,只是提醒下,网上有解决方法,可以自行查阅。

Java上传下载excel、解析Excel、生成Excel的更多相关文章

  1. Java 上传下载的

    1.上传的步骤: a.导入SmartUpload.jar    b.创建一个上传的类的对象    c.初始化   d.上传至服务器   e.保存    注意:表单提交时需要指定enctype=&quo ...

  2. 【java 上传+下载】

    一.先说说上传 第一步:pom.xml文件 加上 上传文件依赖架包 <dependency> <groupId>commons-fileupload</groupId&g ...

  3. [Azure Storage]使用Java上传文件到Storage并生成SAS签名

    Azure官网提供了比较详细的文档,您可以参考:https://azure.microsoft.com/en-us/documentation/articles/storage-java-how-to ...

  4. Java上传且后台解析XML文件

    后台代码: import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.InputStream ...

  5. WebService完成文件上传下载

    由于开发需要使用webservice,第一个接触的工具叫axis2.项目开发相关jar下载. service端: 启动类: import java.net.InetAddress; import ja ...

  6. java上传excel文件及解析

      java上传excel文件及解析 CreateTime--2018年3月5日16:25:14 Author:Marydon 一.准备工作 1.1 文件上传插件:swfupload: 1.2 文件上 ...

  7. java:工具(汉语转拼音,压缩包,EXCEL,JFrame窗口和文件选择器,SFTP上传下载,FTP工具类,SSH)

    1.汉语转拼音: import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin4j.format.HanyuP ...

  8. 简单Excel表格上传下载,POI

    一.废话 Excel表格是office软件中的一员,几乎是使用次数最多的办公软件.所以在java进行企业级应用开发的时候经常会用到对应的上传下载便利办公. 目前,比较常用的实现Java导入.导出Exc ...

  9. ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案 try.dot.net 的正确使用姿势 .Net NPOI 根据excel模板导出excel、直接生成excel .Net NPOI 上传excel文件、提交后台获取excel里的数据

    ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案   ASP.NET Core 从2.2版本开始,采用了一个新的名为Endpoint的路由方案,与原来的方案在使用上差别不 ...

随机推荐

  1. MBProgressHUD基础用法

    MBProgressHUD版本号:0.9.2以前用MBProgressHUD用得挺好的,基本上 - (void)showAnimated:(BOOL)animated whileExecutingBl ...

  2. CSS: Grid Layout Module

    Grid Layout The CSS Grid Layout Module offers a grid-based layout system, with rows and columns, mak ...

  3. 第7课:sql注入、操作session、cookie实例、网络编程、操作Excel

    1. 简单讲一些sql注入的内容 name = 'zdq' sex = '女' cur.execute("select * from bt_stu where real_name='%s'& ...

  4. MySQL学习(三): 初识数据表

    打开数据库: USE db_name : 打开数据库. 创建数据表: 查看数据表: 查看数据表结构: 数据简单的插入与查找: 插入:INSERT [INTO] tbl_name [(col_name) ...

  5. APUE学习笔记——8.11 实际用户ID、有效用户ID、设置用户ID

    用户ID的基本概念 在Unix系统中,很多操作涉及到权限问题,这些权限涉及到用户ID和组ID的概念.     组ID和用户ID的原理和相关内容是类似的.下面介绍用户ID.     我们常见见到三种关于 ...

  6. Function.bind 方法

    this.num = 9; var mymodule = { num: 81, getNum: function() { return this.num; } }; module.getNum(); ...

  7. Linux:paste命令详解

    paste 直接将两行贴在一起,且中间以[TAB]键隔开 语法 paste(选项)(file1 file2) 选项 -d<间隔字符>或--delimiters=<间隔字符>:用 ...

  8. Django-RestfulFramework --- DRF

    >> (1)RESTful api 规范 和 DRF 的基本介绍 >> (2)DRF 的 认证系统实现 >> (3)DRF 的 权限系统实现 >> (4 ...

  9. 缺一个UI设计

    这几天弄小程序的界面真的是太艰难了,神呐,请赐我一个UI吧 甚至,在第二种布局下的渐变过渡,都拿笔来计算了TT 还有这个色调的选择,在避免过渡效果突兀的处理上,真的是很费工夫啊: 我谁都不服,就服那些 ...

  10. 随想录(kgdb的基本原理)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 在linux kernel调试的时候,有一种很方便的调试方法,那就是kgdb.kgdb的本质,就 ...