Java学习之道:Java上传下载excel、解析Excel、生成Excel的问题

在软件开发过程中难免需要批量上传与下载,生成报表保存也是常有之事,最近集团门户开发用到了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学习之道:Java上传下载excel、解析Excel、生成Excel的问题

时间: 2024-10-25 11:22:34

Java学习之道:Java上传下载excel、解析Excel、生成Excel的问题的相关文章

Java学习之道:Java 导出EXCEL

1.Apache POI简介 Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程式对Microsoft Office格式档案读和写的功能. .NET的开发人员则可以利用NPOI (POI for .NET) 来存取 POI 的功能. 2.POI结构 HSSF - 提供读写Microsoft Excel XLS格式档案的功能. XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能. HWPF - 提供读写Microsoft

Java学习之道:使用JAXP进行DOM解析( DocumentBuilderFactory、DocumentBuilder、Document)

1.javax.xml.parsers 包中的DocumentBuilderFactory用于创建DOM模式的解析器对象 , DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法 ,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回 2.调用 DocumentBuilderFactory.newInstance() 方法得到创建 DOM 解析器的工厂. 3.调用工厂对象的 newDocumentBuilder

pycurl之公共方法--请求/上传/下载,解析json

1 # -*- coding=utf-8 -*- 2 #curl公共程序 3 #张明伟 20200331 4 import pycurl 5 from io import BytesIO 6 import datetime,time,os 7 import logging 8 import json 9 from logging import handlers 10 testdebug=1 #测试模式:1为是,0为否 11 if testdebug: 12 ip = '221.122.125.2

Java Web(十二) commons-fileupload上传下载

今天心态正常...继续努力.. --WH 一.上传原理和代码分析. 上传:我们把需要上传的资源,发送给服务器,在服务器上保存下来. 下载:下载某一个资源时,将服务器上的该资源发送给浏览器. 难点:服务器端获取资源时比较麻烦, 浏览器端 注意:enctype=multipart/form-data:该属性表明发送的请求体的内容是多表单元素的,通俗点讲,就是有各种各样的数据,可能有二进制数据,也可能有表单数据,等等,所以使用该属性也进行其区分,发送的格式如下(使用火狐中的Firebug插件进行捕捉的

Struts2学习笔记(十一)——文件上传下载

1.单文件上传 单文件上传步骤: 1)创建上传jsp页面 文件上传的表单提交方式必须是POST方式,编码类型:enctype="multipart/form-data",默认是 application/x-www-form-urlencoded,比如: 1 <form action="${pageContext.servletContext.contextPath}/uploadAction.action" enctype="multipart/fo

java web 文件上传下载

文件上传下载案例: 首先是此案例工程的目录结构: 处理上传: FileUploadServlet.java 1 package fnz.fileUploadTest; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.PrintWriter; 7 import java.text.SimpleDateFormat; 8 import java.

Java Sftp上传下载文件

需要使用jar包  jsch-0.1.50.jar sftp上传下载实现类 package com.bstek.transit.sftp; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import co

JAVA中使用FTPClient实现文件上传下载

在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件.下载文件,本文简单介绍如何利用jakarta commons中的FTPClient(在commons-net包中)实现上传下载文件. 一.上传文件 原理就不介绍了,大家直接看代码吧 /** * Description: 向FTP服务器上传文件 * @Version1.0 Jul 27, 2008 4:31:09 PM by 崔红保([email protected])创建 * @param url FTP服务器hostname

Java通过FTP服务器上传下载文件的解决方案

对于使用文件进行交换数据的应用来说,使用FTP 服务器是一个很不错的解决方案.本文使用Apache Jakarta Commons Net(commons-net-3.3.jar)基于FileZilla Server服务器实现FTP服务器上文件的上传/下载/删除等操作. 关于FileZilla Server服务器的详细搭建配置过程,详情请见FileZilla Server安装配置教程.之前有朋友说,上传大文件(几百M以上的文件)到FTP服务器时会重现无法重命名的问题,但本人亲测上传2G的文件到F