精华内容
下载资源
问答
  • java实现excel打压缩包下载

    千次阅读 2018-10-31 10:04:12
    1.设置HTTP协议的响应头       Http协议的请求被封装在了HttpServletRequest里面,而响应则被封装在了HttpServletResponse,不管...

    最近做了这个功能的需求,总结一下,实现这个功能步骤为三步。

    1.设置HTTP协议的响应头
          Http协议的请求被封装在了HttpServletRequest里面,而响应则被封装在了HttpServletResponse,不管使用的是什么框架spring mvc还是自己公司封装的框架,都要先拿出response。

    response.setHeader("Content-Type","application/octect-stream");
    response.setHeader("Content-Disposition","attachment;filename=test.zip");
    

          告诉浏览器,要传输二进制流文件,和文件名,响应结果,chrome浏览器利用审查的network,查看响应头是否设置成功。
    查看结果

    2.拿到response的输出流,初始化ZipOutputStream
          初始化ZipOutputStream的时候需要传入一个OutputStream,此时我们将response的OutputStream作为实参传给ZipOutputStream(这个OutputStream能够写HTTP响应的实体内容)

    OutputStream outputStream = response.getOutputStream();
    ZipOutputStream zipOut = new ZipOutputStream(outputStream); 
    // 设置注释
    zipOut.setComment("welcome to here to look look");
    

           想要压缩包里面有多个excel文件的话就向Zipout里面添加多个ZipEntry,设置的注释就是这个
    在这里插入图片描述

    byte[] buffer = new byte[5*1024];
    int length = 0;
    for (int j = 0; j < data.size(); j++) {
                List list = data.get(j);
                String fileName = "test"+j+".xls";
                zipOut.putNextEntry(new ZipEntry(fileName));
                InputStream inputStream = createExcel(list);
                while ((length = inputStream.read(buffer)) != -1) {
                    zipOut.write(buffer,0,length);
                }
                inputStream.close();
    }
    zipOut.close();
    

    这里的data是一个List<List<Map>> ,装的数据就是想写进excel里面的数据。createExcel() 这函数就是我们的第三步了。

    3.这一步主要是创建excel的实体,和输出流转输入流。

    public InputStream createExcel(List list) throws Exception{
    	//第一步创建workbook
        HSSFWorkbook wb = new HSSFWorkbook();
    
        //第二步创建sheet
        HSSFSheet sheet = wb.createSheet("表1");
        HSSFSheet sheet2 = wb.createSheet("表2");
        HSSFSheet sheet3 = wb.createSheet("表3");
        
    	//第三步创建行row:添加表头0行(表1)
        HSSFRow row = sheet.createRow(0);
        HSSFCellStyle style = wb.createCellStyle();
        
        //第四步创建单元格
        HSSFCell cell = row.createCell(0); //第一个单元格
        cell.setCellValue("编号");
        cell.setCellStyle(style);
        .....
        
        //第五步插入数据
        List list1 = result.get(0);
        for (int i = 0; i < list1.size(); i++) {
            //创建行
            row = sheet.createRow(i+1);
            //创建单元格并且添加数据
            row.createCell(0).setCellValue(list1.get(i).getAt("id"));
         	 .....
        }
    	// 重复以上操作给余下的sheet添加表头和数据
    	....
    
     //第六步将生成excel转化为输入流返回
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            wb.write(outputStream);
            ByteArrayInputStream swapStream = new ByteArrayInputStream(outputStream.toByteArray());
            return swapStream;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    表1、表2、表3就是excel里面的这个
    在这里插入图片描述

    然后就没有然后了,前端直接请求就行了。

    展开全文
  • Java下载Excel文件

    千次阅读 2017-10-03 14:09:35
    在线实时生成Excel文件流供下载  我做过的一个项目,需要实现在线实时生成 Excel文件...所以采取了在服务器端生成文件输出流(ServletOutputStream),通过HttpServletResponse对象设置相应的响应头,然后将此输出流
    
      我做过的一个项目,需要实现在线实时生成 Excel文件供客户端下载的需求,最初考虑的是先在服务器端生成真实的文件,然后在客户端下载该文件。后来发现这样做不但性能不够好、速度较慢,而且还要占用服务器空间。所以采取了在服务器端生成文件输出流(ServletOutputStream),通过HttpServletResponse对象设置相应的响应头,然后将此输出流传往客户端的方法实现。在实现过程中,用到了Apache组织的Jakarta开源组件POI,读者朋友可到其官方网站查阅相关资料及下载。现将整个实现过程介绍如下:

             一、首先,根据Excel表的特点,我编写了一个Excel表模型类ExcelModel,代码如下:

    package com.qnjian.myprj.excel;

    import java.util.ArrayList;

    /**
     *
     * <p>Title: ExcelModel</p>
     *
     * <p>Description: Excel表的操作模型</p>
     *
     * <p>Copyright: Copyright (c) 2005-10-20</p>
     *
     * <p>Company: *** </p>
     *
     * 
    @author zzj
     * 
    @version 1.0
     
    */


    public class ExcelModel {
          
    /**
           * 文件路径,这里是包含文件名的路径
           
    */

          
    protected String path;
          
    /**
           * 工作表名
           
    */

          
    protected String sheetName;
          
    /**
           * 表内数据,保存在二维的ArrayList对象中
           
    */

          
    protected ArrayList data;
          
    /**
           * 数据表的标题内容
           
    */

          
    protected ArrayList header;
          
    /**
           * 用于设置列宽的整型数组
           * 这个方法在程序中暂未用到
           * 适用于固定列数的表格
           
    */

          
    protected int[] width;

          
    public ExcelModel() {
                path
    ="report.xls";
          }


          
    public ExcelModel(String path) {
               
    this.path=path;
         }



          
    public void setPath(String path){
               
    this.path=path;
          }


          
    public String getPath(){
                
    return this.path;
          }

          
          
    public void setSheetName(String sheetName){
              
    this.sheetName=sheetName;
          }

          
          
    public String getSheetName(){
              
    return this.sheetName;
          }


          
    public void setData(ArrayList data){
                
    this.data=data;
          }


          
    public ArrayList getData(){
                
    return this.data;
          }


          
    public void setHeader(ArrayList header){
                
    this.header=header;
          }


          
    public ArrayList getHeader(){
                
    return this.header;
          }


          
    public void setWidth(int[] width){
                
    this.width=width;
          }


          
    public int[] getWidth(){
                
    return this.width;
          }

    }

          
      二、编写一个下载接口ExcelDownLoad,定义基本的方法:

    package com.qnjian.myprj.excel;

    import java.io.IOException;
    import java.util.List;

    import javax.servlet.http.HttpServletResponse;

    import org.apache.struts.action.ActionForm;


    public interface ExcelDownLoad {
        
        
    /**
         * 初始化要生成的Excel的表模型
         * 
    @param list List 填充了 Excel表格数据的集合
         * 
    @param form ActionForm及其子类
         * 
    @param excel ExcelModel Excel表的对象模型
         * 
    @see ExcelModel
         * 
    @throws Exception
         
    */

        
    public ExcelModel createDownLoadExcel (List list, ActionForm form, 
                ExcelModel excel)
    throws Exception;
        
        
    /**
         * 在已文件已存在的情况下,采用读取文件流的方式实现左键点击下载功能,
         * 本系统没有采取这个方法,而是直接将数据传往输出流,效率更高。
         * 
    @param inPutFileName 读出的文件名
         * 
    @param outPutFileName 保存的文件名
         * 
    @param HttpServletResponse     
         * 
    @see HttpServletResponse
         * 
    @throws IOException
         
    */

        
    public void downLoad(String inPutFileName, String outPutFileName,
                HttpServletResponse response) 
    throws IOException ;
        
        
    /**
         * 在已文件不存在的情况下,采用生成输出流的方式实现左键点击下载功能。
         * 
    @param outPutFileName 保存的文件名
         * 
    @param out ServletOutputStream对象    
         * 
    @param downExcel 填充了数据的ExcelModel
         * 
    @param HttpServletResponse     
         * 
    @see HttpServletResponse
         * 
    @throws Exception
         
    */

        
    public void downLoad(String outPutFileName, ExcelModel downExcel,
                HttpServletResponse response) 
    throws Exception ;

    }



             三、编写一个实现了以上接口的公共基类BaseExcelDownLoad,并提供downLoad()方法的公共实现,代码如下:

    /**
     *
     * <p>Title: BaseExcelDownLoad</p>
     *
     * <p>Description:Excel表下载操作基类,生成excel格式的文件流供下载 </p>
     *
     * <p>Copyright: Copyright (c) 2005-10-27</p>
     *
     * <p>Company: *** </p>
     *
     * 
    @author zzj
     * 
    @version 1.0
     
    */

    package com.qnjian.myprj.excel;

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.List;

    import javax.servlet.http.HttpServletResponse;
    import org.apache.struts.action.ActionForm;


    public abstract class BaseExcelDownLoad implements ExcelDownLoad{
        
        
         
    /**
         * 初始化要生成的Excel的表模型
         * 
    @param list List 填充了 Excel表格数据的集合
         * 
    @param form ActionForm及其子类
         * 
    @param excel ExcelModel Excel表的对象模型
         * 
    @see ExcelModel
         * 
    @throws Exception
         
    */

        
    public abstract ExcelModel createDownLoadExcel (List list, ActionForm form, 
                ExcelModel excel)
    throws Exception;
        
        
    /**
         * 在已文件已存在的情况下,采用读取文件流的方式实现左键点击下载功能,
         * 本系统没有采取这个方法,而是直接将数据传往输出流,效率更高。
         * 
    @param inPutFileName 读出的文件名
         * 
    @param outPutFileName 保存的文件名
         * 
    @param HttpServletResponse     
         * 
    @see HttpServletResponse
         * 
    @throws IOException
         
    */

        
    public void downLoad(String inPutFileName, String outPutFileName,
                HttpServletResponse response) 
    throws IOException {        
            
           
    //打开指定文件的流信息
            InputStream is = new FileInputStream(inPutFileName);
            
    //写出流信息
             int data = -1;
             OutputStream outputstream 
    = response.getOutputStream();
             
            
    //清空输出流
               response.reset();             
             
    //设置响应头和下载保存的文件名              
             response.setHeader("content-disposition","attachment;filename="+outPutFileName);
             
    //定义输出类型
             response.setContentType("APPLICATION/msexcel");
             
            
    while ( (data = is.read()) != -1)outputstream.write(data);
            is.close();
            outputstream.close();
            response.flushBuffer();    

        }

        
        
    /**
         * 在文件不存在的情况下,采用生成输出流的方式实现左键点击下载功能。
         * 
    @param outPutFileName 保存的文件名
         * 
    @param out ServletOutputStream对象    
         * 
    @param downExcel 填充了数据的ExcelModel
         * 
    @param HttpServletResponse     
         * 
    @see HttpServletResponse
         * 
    @throws Exception
         
    */

        
    public void downLoad(String outPutFileName, ExcelModel downExcel,
                HttpServletResponse response) 
    throws Exception {
           
            
    //取得输出流
            OutputStream out = response.getOutputStream();
            
    //清空输出流
            response.reset();
            
            
    //设置响应头和下载保存的文件名              
            response.setHeader("content-disposition","attachment;filename="+outPutFileName);
            
    //定义输出类型
            response.setContentType("APPLICATION/msexcel");       
      
            
            ExcelOperator op 
    = new ExcelOperator();
            
    //out:传入的输出流
            op.WriteExcel( downExcel,out);
            out.close();
            
            
    //这一行非常关键,否则在实际中有可能出现莫名其妙的问题!!!
           response.flushBuffer();//强行将响应缓存中的内容发送到目的地                              
        
       
         }


    }


      请注意,BaseExcelDownLoad只是提供了一个生成下载文件流的公共方法,而Excel表格需要显示的数据内容则因具体业务与需求的不同而不同,因此,必须根据具体情况提供一个该类的继承类,实现createDownLoadExcel()方法,以生成所需要输出内容的Excel表格文件流。要说明的是,该方法的参数list ,实际上是一个ArrayList集合,我们将从数据库查询出来的记录集保存在其中,我想这是很容易做到的,实现的方式也可以各种各样。我项目中是通过Hibernate的Query对象取得查询结果集,它正好也是一个ArrayList。不同的客户,甚至不同功能模块内需要生成的Excel报表的内容都是不一样的。下面还是给出我的一个实现类作为例子吧。


      四、实现按照具体的需求生成Excel表格文件流的类举例:继承自BaseExcelDownLoad类的AgentInfoExcelDownLoad:

    package com.qnjian.myprj.excel;

    import java.math.BigDecimal;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    import org.apache.struts.action.ActionForm;

    import com.netease.bid.cs.model.BidAgent;
    import com.netease.bid.cs.model.BidUser;
    import com.netease.bid.cs.util.DateUtil;
    import com.netease.bidding.cs.servlet.InitCsServlet;
    import com.netease.bidding.cs.vo.InstructUser;

    public class AgentInfoExcelDownLoad extends BaseExcelDownLoad {

        
    public ExcelModel createDownLoadExcel(List list, ActionForm form,
                ExcelModel excel) 
    throws Exception {
            
            String titleStr 
    = "客户帐号;公司名称;所属地区;帐户余额;注册日期;联系方式;联系人;";
        
            ArrayList data 
    = new ArrayList();        
            
            Iterator ir 
    = list.iterator();
            
    while(ir.hasNext()){
                
                ArrayList rowData 
    = new ArrayList();
                
                BidAgent user 
    = (BidAgent)ir.next();
            
                rowData.add(user.getName());
                rowData.add(user.getCorpName());            
            
                
    //取得所在省名称
                String provStr = (user.getProvince()==null ) ? 
                        
    "" : InitCsServlet.getProvinceStr(
                        user.getProvince());
                
                
    //取得所在地区名称
                 String cityStr = (user.getCity()==null?
                         
    "" : InitCsServlet.getCityStr(
                       user.getCity());
                
    if(provStr.equals(cityStr)){
                    cityStr 
    = "";
                }

                rowData.add(provStr
    +" "+cityStr);
                
                            BigDecimal balance 
    =user.getReturnBalance().add(user.getBalance());
                rowData.add(balance);            
                
                String date 
    = DateUtil.getFormatDate(user.getCreateTime(),"yyyy-MM-dd");
                rowData.add(date);        
        
                rowData.add(user.getPhone());
                rowData.add(user.getLinkMan());

                data.add(rowData);        
                
            }

            
        
            String[] titles 
    = titleStr.split(";");
            
            
    /*for(int i=0;i<titles.length;i++){
                System.out.print(titles[i]+" ");
            }
    */

            
            ArrayList header 
    = new ArrayList();
            
    for (int i=0;i<titles.length;i++){
                header.add(titles[i]);
            }

            
            
    //设置报表标题
            excel.setHeader(header);
            
    //设置报表内容
            excel.setData(data);
            
    return excel;
        }


    }


            五、编写一个操作类,进行生成下载文件流的操作:

    /**
     *
     * <p>Title: Excel表操作</p>
     *
     * <p>Description:用于生成Excel格式文件 </p>
     *
     * <p>Copyright: Copyright (c) 2005-10-20</p>
     *
     * <p>Company: *** </p>
     *
     * 
    @author zzj
     * 
    @version 1.0
     
    */


    package com.qnjian.myprj.excel;

    import org.apache.poi.hssf.usermodel.*;
    import java.io.FileOutputStream;
    import java.io.BufferedOutputStream;
    import java.util.ArrayList;
    import java.math.BigDecimal;
    import java.io.OutputStream;


    /**
     *实现生成Excel文件的操作
     
    */

    public class ExcelOperator{
        
          
    /**
           * 将数据信息写入到Excel表文件,采取自建输出流的方式。
           * 
    @param excel ExcelModel Excel表的模型对象    
           * 
    @throws Exception
           
    */

         
    public  void WriteExcel(ExcelModel excel)throws Exception{         

          
    try{  
            
           String file 
    = excel.getPath();
           
           
    //新建一输出文件流
           FileOutputStream fOut = new FileOutputStream(file);
           BufferedOutputStream bf 
    =new BufferedOutputStream(fOut);
            
            HSSFWorkbook workbook 
    =this.getInitWorkbook(excel);
            
            
    // 把相应的Excel 工作簿存盘
            workbook.write(fOut);
            fOut.flush();
            bf.flush();
            
    // 操作结束,关闭文件 
            bf.close();
            fOut.close();
           
    // System.out.println("Done!");
          }
    catch(Exception e){
            
    //System.out.print("Failed!");
              throw new Exception(e.getMessage());
             }

          
         }

         
         
         
    /**
          * 将数据信息写入到Excel表文件 ,采取传入输出流的方式。
          * 
    @param excel Excel表的模型对象 
          * 
    @param out  OutputStream 输出流
          * 
    @throws Exception
          
    */

         
    public  void WriteExcel(ExcelModel excel,OutputStream out)throws Exception{
             
    try{
                 HSSFWorkbook workbook 
    =this.getInitWorkbook(excel);
                 workbook.write(out);          
                    out.close();
                
    // System.out.println("Done!");
             }
    catch(Exception e){
                 
    //System.out.println("Failed!");
                 throw new Exception(e.getMessage());
             }

             
             
         }

        
        
    /**
         * 取得填充了数据的工作簿
         * 
    @param excel ExcelModel Excel表的模型对象
         * 
    @return HSSFWorkbook 工作簿对象
         
    */

        
    private  HSSFWorkbook getInitWorkbook(ExcelModel excel){
                

                
    // 创建新的Excel 工作簿
                HSSFWorkbook workbook = new HSSFWorkbook();

                 
    //在Excel工作簿中建一工作表
                 HSSFSheet sheet = null;
                 String sheetName 
    = excel.getSheetName();
                 
                 
    if(sheetName!=null)sheet=workbook.createSheet(sheetName);
                 
    else sheet=workbook.createSheet();

                 
    //设置表头字体
                 HSSFFont font_h = workbook.createFont();
                 font_h.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

                 
    //设置格式
                 HSSFCellStyle cellStyle= workbook.createCellStyle();
                 cellStyle.setFont(font_h);            


                  
    //在索引0的位置创建行(最顶端的行)
                   HSSFRow row = sheet.createRow((short)0);

                   ArrayList header 
    = excel.getHeader();
                   
    if(header!=null){
                       
    for(int i=0;i<header.size();i++){

                      
    //在索引0的位置创建单元格(左上端)
                      HSSFCell cell = row.createCell((short)i);
                      
    // 定义单元格为字符串类型
                     cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                     
    //设置解码方式
                     cell.setEncoding((short)1);
                     
    //设置单元格的格式
                     cell.setCellStyle(cellStyle);
                     
    // 在单元格中写入表头信息
                     cell.setCellValue((String)header.get(i));

                       }

                   }


                   ArrayList cdata 
    = excel.getData();
                   
    for (int i=0;i<cdata.size();i++){
                    
    //从第二行开始
                    HSSFRow row1 = sheet.createRow(i+1);
                    ArrayList rdata 
    =(ArrayList)cdata.get(i);
                   
    //打印一行数据
                    for (int j=0;j<rdata.size();j++){

                        HSSFCell cell 
    = row1.createCell( (short)j);
                        cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                        
    //设置字符编码方式
                        cell.setEncoding((short)1);
                        
                       Object o 
    = rdata.get(j);
                        
                        
    //造型,使写入到表中的数值型对象恢复为数值型,
                       
    //这样就可以进行运算了
                        if(o instanceof BigDecimal){
                            BigDecimal b
    =(BigDecimal)o;
                            cell.setCellValue(b.doubleValue());
                        }

                        
    else if(o instanceof Integer){
                               Integer it 
    =(Integer)o;
                               cell.setCellValue(it.intValue());
                               
                        }

                        
    else if(o instanceof Long){
                            Long l 
    =(Long)o;
                            cell.setCellValue(l.intValue());
                            
                        }

                        
    else if(o instanceof Double){
                            Double d 
    =(Double)o;
                            cell.setCellValue(d.doubleValue());
                        }

                        
    else if(o instanceof Float){
                            Float f 
    = (Float)o;
                            cell.setCellValue(f.floatValue());
                        }

                        
    else{
                            cell.setCellValue(o
    +"");
                        }
                 
                
                        
                    }


                   }

               
    return workbook;
                
            }


      
    /**
       * Just to test
       * 
    @param args String[]
       
    */

      
    public static void main(String[] args){

                    ArrayList data
    =new ArrayList();
                    ArrayList header 
    = new ArrayList();
                    header.add(
    "学号");
                    header.add(
    "姓名");
                    header.add(
    "成绩");
                    
    for (int i=0;i<3;i++){

                         ArrayList data1
    =new ArrayList();

                                data1.add((i
    +1)+"");
                                data1.add(
    "Name"+(i+1));
                                data1.add(
    ""+(80+i));
                                data.add(data1);
                    }

                    ExcelModel model 
    = new ExcelModel();
                    model.setPath(
    "E:/test.xls");
                    model.setHeader(header);
                    model.setData(data);
                    ExcelOperator eo
    = new ExcelOperator();
                   
    try{
                      eo.WriteExcel(model);
                   }
    catch(Exception e){
                         System.out.println(e.getMessage());
                   }


            }

    }



             六、功能流程小结:

             涉及到不同的项目,采取的框架与结构是可能不同的。我的实现方法可以应用到不同的项目中去,只是作为一个借鉴,它可能需要针对不同情况做相应调整与修改。
             我的项目是采取了Spring+Struts+Hibernate的框架实现的,显示层仍然使用HTML、JSP文件,通过它传递客户端的请求,转到Action类调用业务逻辑对象实现相应功能。持久层使用了Hibernate,使用Hibernate作为数据持久层,在开发与维护方面都带来了较大的便利。至于相关框架的配置与实现,则不在本文论述的范围,请读者朋友参阅相关资料。我的项目中,使用了一个Service类(类似Manager的功能,编写接口与实现类,在Spring配置文件中加入,利用Spring的依赖注入技术在运行中取得对应的Bean实例......)来集成业务逻辑功能,通过它调用涉及到的数据访问类(DAO类),具体Dao类又利用Hibernate提供的对象进行数据库的查询或其他操作。这些东西,我就不再详述了,相信对这些技术使用得比我娴熟者大有人在。功能的最终实现,请看我在某个Action中的几行代码:

     ExcelModel excel = new ExcelModel();
                             excel.setSheetName(
    "BidCost");                           
                                     
                                
    //写入到Excel格式输出流供下载
                               try{                           
                             
                                    
    //调用自编的下载类,实现Excel文件的下载
                                   ExcelDownLoad downLoad = new BidCostExcelDownLoad();
                                   ExcelModel downExcel
    = downLoad.createDownLoadExcel(bidReportList,bcf,excel);
                                   
    //不生成文件,直接生成文件输出流供下载
                                   downLoad.downLoad("BidCost.xls",downExcel,response);
                                   
                                   log.info(
    "create Excel outputStream successful!");                               
                               
                               }
    catch(Exception e){
                                   msg.add(ActionMessages.GLOBAL_MESSAGE, 
    new ActionMessage(
                                           
    "bidding.cs.fileUpDown.fileDownError"));//文件下载失败!
                                      saveErrors(request, msg);                                
                                  
                                     log.info(
    "create Excel outputStream  failed!");
                                  log.info(e.getMessage());
                                  
    //e.printStackTrace();
                                  
                                  
    return mapping.getInputForward();                             

                               }
                           
    展开全文
  • 在应用开发中,经常需要下载文件(如导出Excel),调用后台接口时,如果后台报错需要弹出错误信息,如果没有报错正常下载文件。...1、实现思路方法一:通过原生Ajax响应头来区分是文本还是流,然后通过blob...

    在应用开发中,经常需要下载文件(如导出Excel),调用后台接口时,如果后台报错需要弹出错误信息,如果没有报错正常下载文件。本文主要介绍前台及后台(基于java)的处理方法,文中使用到的软件版本:Spring 4.3.9、Java 1.8.0_191、Jquery 1.12.4、Chrome 85.0.4183.121。

    1、实现思路

    方法一:通过原生Ajax响应头来区分是文本还是流,然后通过blob来处理返回数据

    方法二:分成两个接口,先调用生成文件的接口,如果文件成功生成则再调用文件下载的接口;如果文件生成失败则弹出失败信息

    2、方法一(Ajax响应头区分文本还是流)

    2.1、后台

    /*** 根据sql导成csv;成功返回文件流,失败返回错误信息

    *@paramsql 导出sql

    *@paramcol 字段信息,以逗号分隔

    *@paramtitle 文件头信息,以逗号分隔

    *@paramseparator csv文件的分隔符*@paramrequest

    *@paramresponse*/@RequestMapping("exportForCsv.do")

    @ResponseBodypublic CallResultexportForCsv(String sql, String col, String title, String separator, String fileName, HttpServletRequest request, HttpServletResponse response) {

    logger.info("sql={}", sql);

    logger.info("title={}", title);

    logger.info("separator={}", separator);

    logger.info("fileName={}", fileName);

    logger.info("baseServiceName={}", baseServiceName);

    CallResult result = null;

    ByteArrayOutputStream baos= null;

    InputStream in= null;try{if(Util.isNull(separator)) {

    separator= ",";

    }if(Util.isNull(fileName)) {

    fileName= "data.csv";

    }

    baos= newByteArrayOutputStream();getService().exportForCsv(baos, sql, col, title, separator);//这边调用service把文件写入输入流,请自行实现

    in= newByteArrayInputStream(baos.toByteArray());

    writeStream(in, fileName, request, response);

    }catch(Exception e) {

    result= new CallResult<>(-1, "发生异常");

    e.printStackTrace();

    }finally{

    FileUtil.close(baos);

    FileUtil.close(in);

    }returnresult;

    }private void writeStream(InputStream in, String fileName, HttpServletRequest request, HttpServletResponse response) throwsIOException {

    OutputStream out= null;try{

    String urlFileName= "";if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {

    urlFileName= new String(fileName.getBytes("UTF-8"), "ISO8859-1");

    }else{

    urlFileName= java.net.URLEncoder.encode(fileName, "UTF-8");

    }

    response.reset();

    response.setContentType("application/octet-stream");

    response.setHeader("Content-Disposition", "attachment; filename=\"" + urlFileName + "\"");

    response.setHeader("Connection", "close");

    out= newBufferedOutputStream(response.getOutputStream(), BUFFER_SIZE);byte buf[] = new byte[BUFFER_SIZE];intlen;while ((len = in.read(buf)) != -1) {

    out.write(buf,0, len);

    }

    }finally{

    FileUtil.close(out);

    }

    }

    2.2、前台

    2.2.1、拼接参数

    functionexpForCsv() {

    let sql= "";//请自行设置

    let col = "";//请自行设置

    let title = "";//请自行设置

    let fileName = "";//请自行设置

    $.messager.progress({title : '处理中...'});//easyui控件,可用其他控件

    let xhr= newXMLHttpRequest();

    xhr.open("post", "${pageContext.request.contextPath}/common/export/exportForCsv.do", true);

    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    xhr.responseType= "blob";

    xhr.οnlοad= function() {

    $.messager.progress('close');if (xhr.getResponseHeader("Content-type") == 'application/octet-stream') {

    let url=window.URL.createObjectURL(xhr.response);

    let a= document.createElement("a");

    a.href=url;

    a.style.display= 'none'a.download=fileName;

    a.click();

    window.URL.revokeObjectURL(url);

    a.remove();

    }else{

    let reader= newFileReader();

    reader.addEventListener('loadend', function(e) {

    let data=JSON.parse(e.target.result);

    alert('提示', "系统出错,错误信息为:" + data.description + ",请将该信息提供给代维人员寻求帮助");

    });

    reader.readAsText(xhr.response);

    }

    };

    xhr.send('sql=' + sql + '&col=' + col + '&title=' + title + '&separator=|&t=' + newDate().getTime());

    }

    2.2.2、使用FormData

    functionexpForCsv(type) {

    let sql = "";//请自行设置

    let col= "";//请自行设置

    let title = "";//请自行设置

    let fileName = ";//请自行设置

    $.messager.progress({title : '处理中...'});//easyui控件,可用其他控件

    let xhr = new XMLHttpRequest();

    xhr.open("post", "${pageContext.request.contextPath}/common/export/exportForCsv.do", true);

    //xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    xhr.responseType = "blob";

    xhr.οnlοad= function() {

    $.messager.progress('close');if (xhr.getResponseHeader("Content-type") == 'application/octet-stream') {

    let url=window.URL.createObjectURL(xhr.response);

    let a= document.createElement("a");

    a.href=url;

    a.style.display= 'none'a.download=fileName;

    a.click();

    window.URL.revokeObjectURL(url);

    a.remove();

    }else{

    let reader= newFileReader();

    reader.addEventListener('loadend', function(e) {

    let data=JSON.parse(e.target.result);

    alert('提示', "系统出错,错误信息为:" + data.description + ",请将该信息提供给代维人员寻求帮助");

    });

    reader.readAsText(xhr.response);

    }

    };

    let data= newFormData();

    data.append('sql', getCsql(type));

    data.append('col', col);

    data.append('title', title);

    data.append('separator', '|');

    data.append('t', new Date().getTime() + "");

    xhr.send(data);

    }

    3、方法二(两个接口)

    3.1、后台

    3.1.1、生成文件接口

    /*** 根据sql导成csv;成功返回生成的文件名称,失败返回错误信息

    *@paramsql 导出sql

    *@paramcol 字段信息,以逗号分隔

    *@paramtitle 文件头信息,以逗号分隔

    *@paramseparator csv文件分隔符

    *@parambaseServiceName

    *@return

    */@RequestMapping("exportForCsv2")

    @ResponseBodypublic CallResultexportForCsv2(String sql, String col, String title, String separator) {

    logger.info("sql={}", sql);

    logger.info("col={}", col);

    logger.info("title={}", title);

    logger.info("separator={}", separator);

    logger.info("baseServiceName={}", baseServiceName);

    OutputStream os= null;

    CallResult result = new CallResult<>();try{

    String fileName= "数据信息(" + DateUtil.getCurrentDateString("yyyyMMddHHmmsss") + ").xlsx";

    os= new FileOutputStream(new File(WebconfigFactory.getTempFolder() + "数据信息(" + DateUtil.getCurrentDateString("yyyyMMddHHmmsss") + ").xlsx"));

    getService().exportForCsv(os, sql, col, title, separator);//调用service生成文件内容,请自行实现

    result.setResult(fileName);

    }catch(Exception e) {

    result= new CallResult<>(-1, "发生异常");

    e.printStackTrace();

    }finally{

    FileUtil.close(os);

    }returnresult;

    }

    3.1.2、下载文件接口

    /*** 下载方法

    * 1.点击页面下载,需传参数:

    * fileName:磁盘上文件的名称,必需

    * filePath或pathType或webPath:

    * 文件路径,传其中之一参数即可;

    * filePath是磁盘的绝对路径;

    * pathType是路径类型,对应webconfig.properties中的key

    * webPath是相对web应用的路径,如/spa

    * fileRealName:下载保存后的文件名称,可选;如果为空则与fileName一样

    *

    * 2.后台导出文件下载,需传属性:

    * fileName:磁盘上文件的名称,必需

    * fileRealName:下载保存后的文件名称,可选;如果为空则与fileName一样*/@RequestMapping("download")public voiddownload(HttpServletRequest request, HttpServletResponse response) {

    String filePath= "";

    String fileName= request.getParameter("fileName");

    String fileRealName= "";if (!Util.isNull(fileName)) {

    filePath= request.getParameter("filePath");if(Util.isNull(filePath)) {

    String webPath= request.getParameter("webPath");if(Util.isNull(webPath)) {

    String pathType= request.getParameter("pathType");

    filePath=WebconfigFactory.getValue(pathType);

    }else{//filePath = request.getRealPath(webPath) + System.getProperty("file.separator");

    filePath = request.getServletContext().getRealPath(webPath) + System.getProperty("file.separator");

    }

    }

    fileRealName= request.getParameter("fileRealName");

    }else {//后台导出文件下载

    fileName = (String) request.getAttribute("fileName");

    filePath=WebconfigFactory.getTempFolder();

    fileRealName= (String) request.getAttribute("fileRealName");

    }if(Util.isNull(fileRealName)) {

    fileRealName=fileName;

    }

    BufferedInputStream bis= null;

    OutputStream out= null;try{

    String userInfoHeader= "User-Agent";

    String firefoxName= "firefox";

    String urlFileName= "";if (request.getHeader(userInfoHeader).toLowerCase().indexOf(firefoxName) > 0) {

    urlFileName= new String(fileRealName.getBytes("UTF-8"), "ISO8859-1");

    }else{

    urlFileName= java.net.URLEncoder.encode(fileRealName, "UTF-8");

    }

    response.reset();

    response.setContentType("application/octet-stream");

    response.setHeader("Content-Disposition", "attachment; filename=\"" + urlFileName + "\"");

    response.setHeader("Connection", "close");

    bis= new BufferedInputStream(new FileInputStream(filePath +fileName), BUFFER_SIZE);

    out= newBufferedOutputStream(response.getOutputStream(), BUFFER_SIZE);byte[] buf = new byte[BUFFER_SIZE];intlen;while ((len = bis.read(buf)) != -1) {

    out.write(buf,0, len);

    }

    }catch(Exception e) {

    e.printStackTrace();

    }finally{

    FileUtil.close(bis);

    FileUtil.close(out);

    }

    }

    3.2、前台

    functionexp() {

    let sql= "";//请自行设置

    let col = "";//请自行设置

    let title = "";//请自行设置

    $.messager.progress({title : '处理中...'});//easyui控件,可用其他控件

    $.getJSON("${pageContext.request.contextPath}/common/export/exportForCsv2.do",

    {

    sql : sql,

    col : col,

    title : title,

    separator: "|",

    t :newDate().getTime()

    },function(data) {

    $.messager.progress('close');//easyui控件,可用其他控件

    if (data.returnCode == 0) {

    location.href= "${pageContext.request.contextPath}/common/upDownload/download.do?fileName=" + encodeURI(data.result) + "&fileRealName=" + encodeURI("数据.csv") + "&pathType=path.temp.folder";

    }else{

    $.messager.alert('提示', "系统出错,错误信息为:" + data.description + ",请将该信息提供给代维人员寻求帮助");

    }

    }

    );

    }

    注意例子里sql是从台传到后台,这样容易引起SQL注入攻击;严谨的做法应该是前台传参数,后台拼sql,并使用PrepareStatement来执行sql。

    展开全文
  • 介绍了应用Java Web进行程序开发各个方面知识和技巧,主要包括Java Web编程基础、文件操作管理、图形图像与多媒体技术、窗体应用技术、JSP操作Word与Excel等。全书分6篇23章,共计600个实例和600个经验技巧。每...
  • 第2章 Java语言基础 20 2.1 基本语法 21 2.2 运算符 25 2.3 条件语句 29 2.4 循环控制 34 2.5 常用排序 42 2.6 算法应用 48 第3章 HTML/CSS技术 53 3.1 页面效果 54 3.2 表格样式 64 3.3 鼠标样式 72 3.4 文字及列表...
  • 第2章 Java语言基础 20 2.1 基本语法 21 2.2 运算符 25 2.3 条件语句 29 2.4 循环控制 34 2.5 常用排序 42 2.6 算法应用 48 第3章 HTML/CSS技术 53 3.1 页面效果 54 3.2 表格样式 64 3.3 鼠标样式 72 3.4 文字及列表...
  • 第2章 Java语言基础 20 2.1 基本语法 21 2.2 运算符 25 2.3 条件语句 29 2.4 循环控制 34 2.5 常用排序 42 2.6 算法应用 48 第3章 HTML/CSS技术 53 3.1 页面效果 54 3.2 表格样式 64 3.3 鼠标样式 72 3.4 文字及列表...
  • 介绍了应用Java Web进行程序开发各个方面知识和技巧,主要包括Java Web编程基础、文件操作管理、图形图像与多媒体技术、窗体应用技术、JSP操作Word与Excel等。全书分6篇23章,共计600个实例和600个经验技巧。每...
  • 这里有我线程池的实现: <pre name="code" class="java"> logger.debug("启动"); // 获得抓取配置数据 List songsList = songsService.getSongs(); List provList = provService.getProvs(); ...
  • 18.2.html 使用Ajax获取全部响应头信息。 第19章(\c19) 示例描述:演示常用Ajax应用实例。 ajaxmodel.war Ajax实例应用项目文件(可直接在Tomcat中发布运行)。 \ajaxmodel\amel\...
  • 实现了一系列非平台相关IO相关接口和实现,比如提供了对os中系统相关IO功能封装。我们在进行流式读写(比如读写文件)时,通常会用到该包。 bufio 它在io基础上提供了缓存功能。在具备了缓存功能后, ...

空空如也

空空如也

1 2 3
收藏数 54
精华内容 21
关键字:

java实现excel的响应头

java 订阅