Java文件上传与下载
在项目开发中难免遇到这样的问题,对于我这种小白,那只能寻求度娘的帮助拉,各种搜索和看博客文章,当实际运行时。。。。哎,痛苦。
今日分享一波,望你所用,烦闷去之。
文件上传
- 首先在pom文件中导入依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
- 创建上传文件的接口
@RequestMapping("/upload")
@ResponseBody
public R upload(@RequestParam("file")MultipartFile file) {
R r = new R();
// 获取上传的文件的名称 导入Excel模板.xls
// 获取信息
List<excelMember> getMsg = excelservice.getMsg(file);
if(getMsg == null || getMsg.size() == 0) {
r.put("msg","获取到的表格没有数据,请确认文件内容无误!");
}else {
// 保存获取到的数据信息
// r = excelservice.saveMsg(getMsg);
}
r.put(getMsg);
return r;
}
3.获取上传文件的具体实现,这里没有实体代码,可根据自己的进行修改
public List<excelMember> getMsg(MultipartFile file) {
// TODO Auto-generated method stub
//excelMember为你的实体类
excelMember mem = null;
List<excelMember> list = new ArrayList<excelMember>();
try {
//readExcel方法是读取上传文件内容
List<String[]> readExcel = readExcel(file);
for (String[] strings : readExcel) {
mem = new excelMember();
String username =strings[0];
//对容易出现空的进行判断,我这里不严谨,可以根据自己实体进行修改
//获取每行内容
if(username == null || username == "") {
return null;
}else {
mem.setUsername(username);
mem.setUname(strings[1]);
mem.setCity(strings[2]);
String password = strings[3];
mem.setPassword(MD5Utils.encrypt(username, password));
mem.setEmail(strings[4]);
mem.setMobile(strings[5]);
String rmarek = strings[6];
if(rmarek == null || "".equals(rmarek)) {
logger.error("用户:"+strings[1]+"为空!");
mem.setRemark(null);
}else {
mem.setRemark(rmarek);
}
mem.setRole_name(strings[7]);
mem.setStatus(strings[8]);
list.add(mem);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}
- 读取文件内容
public List<String[]> readExcel(MultipartFile file) throws IOException{
//检查文件
checkFile(file);
//获得Workbook工作薄对象
Workbook workbook = getWorkBook(file);
//创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回
List<String[]> list = new ArrayList<String[]>();
if(workbook != null){
for(int sheetNum = 0;sheetNum < workbook.getNumberOfSheets();sheetNum++){
//获得当前sheet工作表
Sheet sheet = workbook.getSheetAt(sheetNum);
if(sheet == null){
continue;
}
//获得当前sheet的开始行
int firstRowNum = sheet.getFirstRowNum();
//获得当前sheet的结束行
int lastRowNum = sheet.getLastRowNum();
//循环除了第一行的所有行
for(int rowNum = firstRowNum+1;rowNum <= lastRowNum;rowNum++){
//获得当前行
Row row = sheet.getRow(rowNum);
if(row == null){
continue;
}
//获得当前行的开始列
int firstCellNum = row.getFirstCellNum();
//获得当前行的列数
int lastCellNum = row.getPhysicalNumberOfCells();
String[] cells = new String[row.getPhysicalNumberOfCells()];
//循环当前行
for(int cellNum = firstCellNum; cellNum < lastCellNum;cellNum++){
Cell cell = row.getCell(cellNum);
cells[cellNum] = getCellValue(cell);
}
list.add(cells);
}
}
workbook.close();
}
return list;
}
public static void checkFile(MultipartFile file) throws IOException{
//判断文件是否存在
if(null == file){
logger.error("文件不存在!");
throw new FileNotFoundException("文件不存在!");
}
//获得文件名
String fileName = file.getOriginalFilename();
//判断文件是否是excel文件
if(!fileName.endsWith(xls) && !fileName.endsWith(xlsx)){
logger.error(fileName + "不是excel文件");
throw new IOException(fileName + "不是excel文件");
}
}
别忘了在头部定义
private final static String xls = "xls";
private final static String xlsx = "xlsx";
public static Workbook getWorkBook(MultipartFile file) {
//获得文件名
String fileName = file.getOriginalFilename();
//创建Workbook工作薄对象,表示整个excel
Workbook workbook = null;
try {
//获取excel文件的io流
InputStream is = file.getInputStream();
//根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
if(fileName.endsWith(xls)){
//2003
workbook = new HSSFWorkbook(is);
}else if(fileName.endsWith(xlsx)){
//2007
workbook = new XSSFWorkbook(is);
}
} catch (IOException e) {
logger.info(e.getMessage());
}
return workbook;
}
public static String getCellValue(Cell cell){
String cellValue = "";
if(cell == null){
return cellValue;
}
//把数字当成String来读,避免出现1读成1.0的情况
if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
cell.setCellType(Cell.CELL_TYPE_STRING);
}
//判断数据的类型
switch (cell.getCellType()){
case Cell.CELL_TYPE_NUMERIC: //数字
cellValue = String.valueOf(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING: //字符串
cellValue = String.valueOf(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN: //Boolean
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA: //公式
cellValue = String.valueOf(cell.getCellFormula());
break;
case Cell.CELL_TYPE_BLANK: //空值
cellValue = "";
break;
case Cell.CELL_TYPE_ERROR: //故障
cellValue = "非法字符";
break;
default:
cellValue = "未知类型";
break;
}
return cellValue;
}
文件上传中部分信息可根据自己实际情况进行修改,或你有什么更好的建议,欢迎留言哟!
文件下载
- 创建下载的接口
@RequestMapping("/download")
@ResponseBody
public R download() {
R r = new R();
Map<String, List<String>> memberMap = excelservice.getMember();
String[] strArray = excelTitle();
String tableName = "Excel模板.xls";
if (memberMap!=null){
excelservice.createExcel(memberMap, strArray,tableName);
r.put("success","success");
r.put("msg","下载成功!");
}else {
r.error(500, "未知异常,请联系管理员");
}
return r;
}
- 创建表的title
/**
* 创建excel title
*/
public static String[] excelTitle() {
String[] strArray = { "*登录用户(不允许重复)", "*用户名", "*城市(**市**区/**县)","*密码","*邮箱","*手机","*备注","*角色","*状态(0:禁用/1:正常)"};
return strArray;
}
3.调用服务方法
public Map<String, List<String>> getMember() {
// TODO Auto-generated method stub
//excelMember为实体对象
List<excelMember> list = new ArrayList<excelMember>();
Map<String, List<String>> map = new HashMap<String, List<String>>();
try {
excelMember excelmember = new excelMember(null,null,null, null, null, null, null, null, null);
list.add(excelmember);
for (int i = 0; i < list.size(); i++) {
ArrayList<String> members = new ArrayList<String>();
// members.add(list.get(i).getUsername() + "");
members.add(list.get(i).getUsername());
members.add(list.get(i).getUname());
members.add(list.get(i).getCity());
members.add(list.get(i).getPassword());
members.add(list.get(i).getEmail());
members.add(list.get(i).getMobile());
members.add(list.get(i).getRemark());
members.add(list.get(i).getRole_name());
members.add(list.get(i).getStatus());
map.put(list.get(i).getUsername() + "", members);
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
4.调用excel的下载方法
/**
* 文件下载
*/
public static void createExcel(Map<String, List<String>> map, String[] strArray,String excelName) {
// TODO Auto-generated method stub
// 第一步,创建一个webbook,对应一个Excel文件
HSSFWorkbook wb = new HSSFWorkbook();
// 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet
HSSFSheet sheet = wb.createSheet("sheet1");
sheet.setDefaultColumnWidth(20);// 默认列宽
// 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
HSSFRow row = sheet.createRow((int) 0);
// 第四步,创建单元格,并设置值表头 设置表头居中
HSSFCellStyle style = wb.createCellStyle();
// 创建一个居中格式
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
// 添加excel title
HSSFCell cell = null;
for (int i = 0; i < strArray.length; i++) {
cell = row.createCell((short) i);
cell.setCellValue(strArray[i]);
cell.setCellStyle(style);
}
// 第五步,写入实体数据 实际应用中这些数据从数据库得到,list中字符串的顺序必须和数组strArray中的顺序一致
int i = 0;
for (String str : map.keySet()) {
row = sheet.createRow((int) i + 1);
List<String> list = map.get(str);
// 第四步,创建单元格,并设置值
for (int j = 0; j < strArray.length; j++) {
row.createCell((short) j).setCellValue(list.get(j));
}
// 第六步,将文件存到指定位置
try {
File file =new File("C:/template");
//如果文件夹不存在则创建
if (!file .exists() && !file .isDirectory())
{
log.debug("文件不存在");
file .mkdir();
} else
{
log.debug("目录存在");
}
//获取本机桌面地址
File desktopDir = FileSystemView.getFileSystemView() .getHomeDirectory();
String desktopPath = desktopDir.getAbsolutePath();
// FileOutputStream fout = new FileOutputStream("C:/template/Excel模板.xls");
//下载到桌面
FileOutputStream fout = new FileOutputStream(desktopPath + "\\" + excelName);
wb.write(fout);
fout.close();
} catch (Exception e) {
e.printStackTrace();
}
i++;
}
}
文件下载如上,接下来就是激动人心的测试环节,本次使用的是内部测试工具,建议可用postman工具进行测试。
之后查看本机桌面找到对应的文件打开后:这里测试所看到的和实际代码中测试应该看到的不一致,是因为测试图片上用到的实体只有用户名这一个,而上面看到的实际测试用改包含一个完整的用户信息,所以,以上述实际为准,此图只为参考。不用怀疑,图片的代码和上述没有区别的。
然后在用户名位置进行添加用户,并保存:
保存后进行上传测试如下:
显而易见的结果啊,我只是小白,欢迎提问。