上传Excel表格(不下载到服务器)并解析到数据库

  • 上传文件的话必须指定form的enctype(encode type,编码类型)属性为multipart/form-data,表示表单数据有多部分组成,既有文本又有文件等二进制数据,指定浏览器使用二进制上传,否则浏览器默认使用ASCII发送数据从而导致文件发送失败。
  • enctype默认为application/x-www-form-urlencoded,只能上传纯文本格式的文件。
  • enctype属性取值:
    • application/x-www-form-urlencoded:在发送前编码all字符。
    • multipart/form-data:不对字符编码,指定传输数据为二进制类型。
    • text/plain:纯文本的传输,空格转换为加号,但不对特殊字符编码。
  • 代码实例:learngit/HPScore/ResolveExcelController、ResolveExcleServiceImpl

步骤

  1. 获取文件的绝对路径。
  2. 获取文件名,如果是中文文件名还需要进行编码。
  3. 设置content-disposition响应头控制浏览器器,告诉浏览器以下载的形式打开文件。
  4. 获取要下载的文件输入流。
  5. 创建数据缓冲区。
  6. 通过response对象获取OutputStream流。
  7. 将文件的FileInputStream流写入buffer缓冲区。
  8. 使用OutputStream将缓冲区的数据输出到客户端浏览器。
使用OutputStream下载中文名文件
public class ServletDemo03 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        this.doPost(request, response);
    }

    /*
     * 主要方法
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {

        //获取文件的下载绝对路径
        String downloadPath=this.getServletContext().getRealPath("/download/示例.jpg");
        //获取文件名
        String fileName=downloadPath.substring(downloadPath.lastIndexOf("\\")+1);
        //设置响应头,告诉浏览器以下载的方式打来文件,设置中文编码,如果不设置会出现乱码
         response.setHeader("content-disposition", 
            "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));

        /*
        * 1. 使用OutputStream字节流
        */
        //获取目标文件的字节输入流
         InputStream is=new FileInputStream(downloadPath);
         //缓冲区
         byte[]b=new byte[1024];
         //获取客户端输出流
         OutputStream os=response.getOutputStream();
         int len=0;
         while((len=is.read(b))!=-1){
             //将缓冲区数据输出到浏览器
             os.write(b,0,len);
         }
         is.close();

         /*
         * 2. 使用PrintWriter字符流
         */
         //获取目标文件的字符输入流
         FileReader fr=new FileReader(downloadPath);
         //缓冲区
         char[] b=new char[1024];
         PrintWriter os=response.getWriter();
         int len=0;
         while((len=fr.read(b))!=-1){
             //将缓冲区数据输出到浏览器
             os.write(b,0,len);
         }
         fr.close();
    }
}
  • 原因:用PrintWriter字符流来处理字节流,会导致数据丢失,因此下载文件时要使用OutputStream.

  • 参考文章