老师,怎样能将上传文件中的数据,写入到服务器本地的一个Excel文件里面去呢?

老师,怎样能将上传文件中的数据,写入到服务器本地的一个Excel文件里面去呢?

以下是我写的代码:

package com.imooc.service;

import com.imooc.dto.ImportExcelParamDto;
import com.imooc.entity.Student;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ExcelService {
    /**
     * 读取上传的Excel文件
     * @param dto(上传的参数对象)
     * @return 返回上传文件中的数据对象
     */
    public List<Student> redExcel(ImportExcelParamDto dto){
        List<Student> impStudentList = new ArrayList<>();
        Workbook workbook=null;
        try {
            //获取上传的Excel文件输入流,并将其传给workbook
            workbook = WorkbookFactory.create(dto.getFile().getInputStream());
            //获得Excel文件的第一个sheet
            Sheet sheet = workbook.getSheetAt(0);
            //获得Sheet下的最后一个有效行
            int rowNum = sheet.getLastRowNum();
            //循环遍历所有有效行数中的单元格,获得单元格中的数据
            for (int i = 1; i <= rowNum; i++) {
                Row row = sheet.getRow(i);
                String name = row.getCell(0).getStringCellValue();
                int age = (int) row.getCell(1).getNumericCellValue();
                Date date = row.getCell(2).getDateCellValue();
                //将获取的数据封装成对象
                Student st = new Student(name,age,date);
                //将封装的对象添加到List中
                impStudentList.add(st);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (workbook != null) {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
       return impStudentList;
    }

    /**
     * 读取服务器本地的Excel文件
     * @param FILE_PATH(服务器本地文件路径)
     * @return 读取到的数据对象集合
     */
    public List<Student> redExcel(String FILE_PATH){
        List<Student> stList = new ArrayList<>();
        Workbook workbook=null;
        try {
            //获取上传的Excel文件输入流,并将其传给workbook
            workbook = WorkbookFactory.create(new File(FILE_PATH));
            //获得Excel文件的第一个sheet
            Sheet sheet = workbook.getSheetAt(0);
            //获得Sheet下的最后一个有效行
            int rowNum = sheet.getLastRowNum();
            //循环遍历所有有效行数中的单元格,获得单元格中的数据
            for (int i = 1; i <= rowNum; i++) {
                Row row = sheet.getRow(i);
                String name = row.getCell(0).getStringCellValue();
                int age = (int) row.getCell(1).getNumericCellValue();
                Date date = row.getCell(2).getDateCellValue();
                //将获取的数据封装成对象
                Student st = new Student(name,age,date);
                //将封装的对象添加到List中
                stList.add(st);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return stList;
    }

    /**
     * 将读取到的上传数据写入到服务器本地的Excel
     * @param FILE_PATH 服务器本地Excel路劲
     * @param impStudentList 要写入到Excel中的数据
     */
    public Workbook writeExcel(String FILE_PATH, List<Student> impStudentList){
        Workbook workbook = null;
        if(impStudentList !=null){
            try {
                workbook = WorkbookFactory.create(new File(FILE_PATH));
                Sheet sheet = workbook.getSheetAt(0);
                int lastRowNum = sheet.getLastRowNum();
                for (int i = lastRowNum+1; i <= lastRowNum+impStudentList.size(); i++) {
                    Row row = sheet.createRow(i);
                    for (Student st : impStudentList){
                        row.createCell(0).setCellValue(st.getName());
                        row.createCell(1).setCellValue(st.getAge());
                        row.createCell(2).setCellValue(st.getDate());
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        else{

        }
        return workbook;
    }
}
package com.imooc.servlet;

import com.imooc.dto.ImportExcelParamDto;
import com.imooc.dto.ParamDto;
import com.imooc.entity.Student;
import com.imooc.service.ExcelService;
import com.imooc.util.RequestUtil;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.poi.ss.usermodel.Workbook;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet(name = "WriteExcelServlet",urlPatterns = "/writeExcel")
public class WriteExcelServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取用户请求数据:1.标题;2文件
        //判断用户请求类型是否为MultipartContent
        if (ServletFileUpload.isMultipartContent(request)){
            //进行请求解析
            ParamDto dto = RequestUtil.parsRequest(request);
            //创建请求文件参数对象
            ImportExcelParamDto paramDto = new ImportExcelParamDto();
            paramDto.setTitle(dto.getParamMap().get("title"));
            paramDto.setFile(dto.getFileMap().get("excel"));
            //开始读取上传文件的数据
            ExcelService excel = new ExcelService();
            List<Student> students = excel.redExcel(paramDto);
            //将文件写入到服务器本地的Excel文件中
            Workbook workbook = excel.writeExcel("c:/upload/Student.xlsx", students);
            ServletOutputStream servletOutputStream = response.getOutputStream();
            workbook.write(servletOutputStream);
            servletOutputStream.flush();
            servletOutputStream.close();
            workbook.close();
            //跳转到RedExcelServlet
            request.getRequestDispatcher("/redExcel").forward(request,response);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
package com.imooc.servlet;

import com.imooc.entity.Student;
import com.imooc.service.ExcelService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet(name = "RedExcelServlet",urlPatterns = "/redExcel")
public class RedExcelServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ExcelService excel = new ExcelService();
        List<Student> students = excel.redExcel("c:/upload/Student.xlsx");
        request.setAttribute("students",students);
        request.getRequestDispatcher("/importExcelResult.jsp");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
package com.imooc.dto;

import org.apache.commons.fileupload.FileItem;

import java.util.HashMap;
import java.util.Map;

/**
 * 提交的请求对象
 * 将提交的每一个请求都放到该对象的Map属性中
 */
public class ParamDto {
    private Map<String,String> paramMap;
    private Map<String, FileItem> fileMap;

    public ParamDto() {
        paramMap = new HashMap<>();
        fileMap = new HashMap<>();
    }

    public Map<String, String> getParamMap() {
        return paramMap;
    }

    public void setParamMap(Map<String, String> paramMap) {
        this.paramMap = paramMap;
    }

    public Map<String, FileItem> getFileMap() {
        return fileMap;
    }

    public void setFileMap(Map<String, FileItem> fileMap) {
        this.fileMap = fileMap;
    }
}
package com.imooc.dto;

import org.apache.commons.fileupload.FileItem;

public class ImportExcelParamDto {
    private String title;
    private FileItem file;

    public ImportExcelParamDto() {
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public FileItem getFile() {
        return file;
    }

    public void setFile(FileItem file) {
        this.file = file;
    }
}
package com.imooc.entity;

import java.util.Date;

public class Student {
    private String name;
    private int age;
    private Date date;

    public Student() {
    }

    public Student(String name, int age, Date date) {
        this.name = name;
        this.age = age;
        this.date = date;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}
package com.imooc.util;

import com.imooc.dto.ParamDto;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

public class RequestUtil {
    public static ParamDto parsRequest(HttpServletRequest request) {
        ParamDto dto = new ParamDto();
        //创建磁盘文件项工厂
        DiskFileItemFactory di = new DiskFileItemFactory();
        //创建核心解析类
        ServletFileUpload sf = new ServletFileUpload(di);
        try {
            //获取请求数据集合List
            List<FileItem> list = sf.parseRequest(request);
            //遍历请求数据集合
            for (FileItem file : list) {
                //判断当前请求是否为文件上传请求
                if (file.isFormField()) {
                    //普通请求
                    //获得请求参数名称和请求参数值
                    String name = file.getFieldName();
                    String value = file.getString("UTF-8");
                    dto.getParamMap().put(name, value);
                } else {
                    //文件上传请求
                    //获得请求参数名称和请求上传文件的数据
                    String name = file.getFieldName();
                    dto.getFileMap().put(name, file);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dto;
    }
}

以上是我写的代码,jsp还是用本节课用的jsp

实际需求,将用户上传的Excel文件中的数据读取出来,然后写入到服务器本地的一个Excel文件当中,再从服务器本地的这个Excel中读取所有的数据,传给浏览器显示出来。

现在遇到的问题:能获取到上传文件中的数据,但是写不进本地的Excel文件中。(写完后不需要下载文件)

请老师帮忙给看看!谢谢

正在回答

登陆购买课程后可参与讨论,去登陆

2回答

同学你好。还是分条来说:

1、create方法使用File还是FileInputStream都是可以的。关键是传入的文件不能为空,因为一定是已经存在的文件才能获得它的workbook:

http://img1.sycdn.imooc.com//climg/5cf1e5cd000174cf12980295.jpg

http://img1.sycdn.imooc.com//climg/5cf1e53300015fa512800266.jpg

2、ServletOutputStream 和 FileOutputStream 都可以作为write的参数传入。只是传入从response中获取的ServletOutputStream,workbook中的内容就写入了response中,也就是在网页上下载了。而直接保存到本地,可以直接为本地文件开启FileOutputStream,令其写到本地。

http://img1.sycdn.imooc.com//climg/5cf1e65c00013b7707500285.jpg

3、文件内容输出有误和上面的两条都没有关系,是因为同学在遍历的时候,循环出了问题:

可以好好看一下impStudentList的结构:

http://img1.sycdn.imooc.com//climg/5cf1e8ae00019db505430395.jpg

应该将内层的for循环给注释掉,并且下标是从0 开始的:

http://img1.sycdn.imooc.com//climg/5cf1ec660001450009760244.jpg

如果解答了同学的疑问,望采纳~

祝学习愉快~


  • China_Wang 提问者 #1
    哈哈哈哈,谢谢老师。输出错误的问题我昨天晚上自己调试出来了。哈哈!
    2019-06-01 12:09:31
芝芝兰兰 2019-05-31 21:14:57

同学你好。下面来一条条解答你的疑惑:

1、在调用WorkbookFactory.create方法之前,inStream 必须对应的是一个已经存在的文件。

inStream = new FileInputStream(new File(FILE_PATH));
 workbook = WorkbookFactory.create(inStream);

2、将文件写入本地只需要将response.getOutputStream()替换成FileOutputStream即可

FileOutputStream fileOutputStream = new FileOutputStream(new File("F:\\测试\\import_04_excel.xls"));
workbook.write(fileOutputStream);

如果解答了同学的疑问,望采纳~

祝学习愉快~


  • 提问者 China_Wang #1
    inStream = new FileInputStream(new File(FILE_PATH)); workbook = WorkbookFactory.create(inStream); 这个地方用到FileInputStream的目的是什么呢?为什么要用这个输入流对象
    2019-05-31 23:02:56
  • 提问者 China_Wang #2
    另外,ServletOutPutStream和FileOutPutStream区别在哪里呢?
    2019-05-31 23:04:17
  • 提问者 China_Wang #3
    我用您给的方法执行后,程序将文件最后一行数据循环输出在了Excel文件里面,而不是所有数据
    2019-05-31 23:07:30
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
从网页搭建入门Java Web2018版
  • 参与学习           人
  • 提交作业       1088    份
  • 解答问题       10205    个

如果你有Java语言基础,又想以后从事Java Web开发,那么本路径是你的不二选择!本路径从网页搭建开始入手,通过大量案例来学习Java Web基础。定能助你完成Java Web小白的蜕变!

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师