之前分享了一个导出excel的功能,导出都有了,那自然需要导入了,不多说,先上代码。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* 获取文件后缀名
* @param path 文件路径
* @return 文件后缀名
*/
public static String getPostfix(String path)
{
if (path == null)
{
return "";
}
if (path.contains("."))
{
return path.substring(path.lastIndexOf(".") + 1, path.length());
}
return "";
}
/**
* 获取Workbook
* @param
* @return Workbook
*/
public static HSSFWorkbook getWorkbook(String fileName) throws Exception
{
HSSFWorkbook wb = null;
// 建立输入流
InputStream input = new FileInputStream(fileName);
// 获取文件后缀名
String filePostFixName = getPostfix(fileName);
// 根据文件格式(2003或者2007)来初始化
/*if (filePostFixName.equals(OFFICE_EXCEL_2010_POSTFIX))
{
wb = new XSSFWorkbook(input);
}
else */if (filePostFixName.equals(OFFICE_EXCEL_2003_POSTFIX))
{
wb = new HSSFWorkbook(input);
}
return wb;
}
/**
* 得到Excel表中的值
*
* @param hssfCell
* Excel中的每一个格子
* @return Excel中每一个格子中的值
*/
private static String getValue(HSSFCell hssfCell,HSSFFormulaEvaluator formulaEvaluator) {
if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
// 返回布尔类型的值
return String.valueOf(hssfCell.getBooleanCellValue());
} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
//返回时间类型的值
if(HSSFDateUtil.isCellDateFormatted(hssfCell)){
Date date = hssfCell.getDateCellValue();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(date);
}
// 返回数值类型的值
return String.valueOf(hssfCell.getNumericCellValue());
}else if(hssfCell.getCellType() == hssfCell.CELL_TYPE_FORMULA){
//返回表达式类型的值
if(formulaEvaluator.evaluate(hssfCell).getStringValue()==null){
return String.valueOf(formulaEvaluator.evaluate(hssfCell).getNumberValue());
}
return String.valueOf(formulaEvaluator.evaluate(hssfCell).getStringValue());
}else if(hssfCell.getCellType() == hssfCell.CELL_TYPE_ERROR) {
//返回未知类型的值
return String.valueOf(hssfCell.getErrorCellValue());
}else{
// 返回字符串类型的值
return String.valueOf(hssfCell.getStringCellValue());
}
}
/**
* 读取excel文件返回map集合
* @param fileName 文件路径
* @param rowStart 从第几行开始读取
* @param cellNum 每行有多少个单元格
* @return 返回一个list,list里面每个元素都是一个map,而map则为装着每一行数据的键值对,如(0,value),代表第一格的值。
*/
public static List<Map> importExcel(String fileName,Integer rowStart,Integer cellNum){
HSSFWorkbook hssfWorkbook = null;
//存放map的list
List<Map> list = new ArrayList<Map>();
try {
hssfWorkbook = getWorkbook(fileName);
HSSFFormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator(hssfWorkbook);
// 循环工作表Sheet
for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) {
HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);
if (hssfSheet == null) {
continue;
}
// 循环行Row
for (int rowNum = rowStart; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
HSSFRow hssfRow = hssfSheet.getRow(rowNum);
if (hssfRow == null) {
continue;
}
//按顺序存放数据的map
Map<Integer,String> map=new LinkedHashMap<Integer,String>();
//通过输入有多少个单元格来存放数据
for(int i=0;i<cellNum;i++){
HSSFCell xh = hssfRow.getCell(i);
map.put(i, getValue(xh,formulaEvaluator));
}
list.add(map);
}
}
}catch (Exception e) {
System.out.println("文件没有读到");
e.printStackTrace();
return null;
}
return list;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~··
工具类有了,自然少不了文件上传了,strus2框架。
因为strus2框架自带文件封装的上传,所以只需要在action层设置两个file变量,和set,get就可以了。
private File[] file; // 附件
private String[] fileFileName; // 附件名称
public String importExcel(){
String root = ServletActionContext.getServletContext().getRealPath("/upload");
InputStream is;
try {
is = new FileInputStream(file[0]);
OutputStream os = new FileOutputStream(new File(root, fileFileName[0]));
byte[] buffer = new byte[500];
while(-1 != (is.read(buffer)))
{
os.write(buffer);
}
os.close();
is.close();
//获取上传的文件的路径
String path = new File(root, fileFileName[0]).toString();
//另外两个参数第一个是从哪一行开始读取,第二个是总共读多少列
//根据excel显示,从第2行开始,每行读33列
List<Map> excelList = ExcelUtil.importExcel(path,1,32);
//数据库操作~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}catch (Exception e) {
System.out.println("获取上传文件失败");
e.printStackTrace();
}
return null;
}
再来springMVC的。
@RequestMapping(value = "uploadExcel")
public String getExcel(HttpServletRequest request){
//创建一个磁盘文件列表工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置缓冲区
factory.setSizeThreshold(1024*1024);
//得到文件的真实路径
String realPath = request.getSession().getServletContext().getRealPath("/").replace("\\","/");
if (!new File(realPath+"temp/").isDirectory()){
new File(realPath+"temp/").mkdir();
}
//设置中转路径
factory.setRepository(new File(realPath+"temp"));
//如不存在此目录,则创建
if (!new File(realPath+"upload/").isDirectory()){
new File(realPath+"upload/").mkdir();
}
if (ServletFileUpload.isMultipartContent(request)){
//创建一个上传文件的对象
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("utf-8");
upload.setFileSizeMax(1024*1024);
upload.setSizeMax(10*1024*1024);
List<FileItem> fileItems=null;
try {
//调用上传文件的方法
fileItems = upload.parseRequest(request);
//遍历得到的文件
for(FileItem file:fileItems){
//如果这个不是一个正常的filedform,而是一个上传文件的form
if( !file.isFormField()){
String name= file.getName();
file.write(new File(realPath+"upload/"+name));
String fileName=realPath+"upload/"+name;
//调用工具类读取excel
//数据库操作
return "xxx";
}else{
System.out.println("出错了");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
前端jsp,再来个提交数据的form表单,大功告成。
<form id="importToExcel" action="xxxxxxxxxx" method="post" enctype="multipart/form-data">
文件上传:<input type="file" name="file">
<input type="submit" value="提交">
</form>
其实理解了原理,读取excel并不难,这里把代码分享出来和大家一起讨论一下,勿喷。