- 浏览: 37677 次
- 性别:
- 来自: 成都
文章分类
最新评论
最近遇到点读取 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 然后下载的方法,如果以后遇到,一定继续完善。
请注意!引用、转贴本文应注明原作者:Rosen Jiang 以及出处:http://www.blogjava.net/rosen
相关推荐
服务器端通常使用Servlet API或者第三方库如Apache Commons FileUpload来接收和处理上传的文件。 2. Excel读取:Java提供了多种读取Excel文件的库,如Apache POI、JExcelAPI和OpenCSV。其中,Apache POI是最常用的...
4. **文件上传处理**:使用Apache Commons FileUpload解析用户的上传请求,获取上传的Excel文件,然后使用JExcelAPI进行读取。 5. **文件下载**:当需要提供Excel文件下载时,可以创建一个Servlet或Controller,将...
下面将详细阐述这个主题,包括如何实现Excel的下载、上传以及解析。 1. **Excel的下载** 下载Excel文件通常涉及将服务器上的文件以HTTP响应的形式发送到客户端。在Java中,我们可以使用Servlet API来实现这一功能...
在Web应用中,如果需要用户上传Excel文件,这个库可以帮助解析上传的数据。以下是一个简单的使用示例: ```java import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload....
- **commons-fileupload.jar**: Apache Commons FileUpload库,用于处理HTTP文件上传,可能在处理用户上传Excel文件时使用。 3. **如何使用Apache POI生成和解析Excel**: - **生成Excel**:首先创建一个`...
- 上传:Java中处理文件上传一般使用Servlet或第三方库如Apache Commons FileUpload。首先,服务器需要配置允许文件上传,然后解析请求获取文件数据,最后将文件保存到服务器指定位置。 - 下载:服务器生成HTTP...
`commons-fileupload.jar` 是Apache Commons项目的一个子项目,它提供了一套强大的工具来处理HTTP请求中的文件上传。在Web应用中,当用户通过表单上传文件时,这些工具能够帮助开发者解析请求,提取上传的文件,并...
在Java中,这可能包括Apache Commons FileUpload或者Spring MVC的MultiPartResolver等。这些库提供了解析HTTP请求中的多部分数据(例如,表单文件上传)的功能,帮助开发者处理文件上传过程中的流控制、错误处理和...
这个过程涉及多个步骤和技术,包括文件上传、Excel数据读取、数据处理以及数据库操作。下面,我们将深入探讨这些关键知识点。 首先,我们需要一个文件上传功能。在Java Web中,通常使用Servlet API或者第三方库如...
本篇文章将详细解析如何通过Java来实现Excel文件的导入,并涵盖必要的技术栈、流程控制以及异常处理等内容。 #### 二、技术栈及依赖 为了实现Java环境下Excel文件的导入功能,我们需要以下几种技术和依赖库的支持...