• 生成 excel 直接用 httpServletResponse 输出


      之前写过一篇文章 《超详细的java生成excel文件并下载》,该文章虽然够详细,也行得通,但还是有一定的缺陷,该文章可以拆分成两个部分,一是指定位置生成excel文件,二是根据地址下载文件。缺陷的部分是会产生中间文件,而这个中间文件我们并不需要,如果每次下载的时候都会生成一个这样的文件,那久而久之岂不是浪费空间,而且生成文件之后再读取输出这样也耗时间。所以今天就对之前的文章进行优化处理下。

            

    package com.test.demo.controllers;
    
    import com.test.demo.domain.entities.Address;
    import com.test.demo.services.ExcelService;
    import jxl.Workbook;
    import jxl.format.Alignment;
    import jxl.format.Border;
    import jxl.format.BorderLineStyle;
    import jxl.format.Colour;
    import jxl.format.*;
    import jxl.format.VerticalAlignment;
    import jxl.write.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.text.SimpleDateFormat;
    import java.util.List;
    
    /**
     * @author dyh
     * @create 2018-11-15 下午10:20
     * @desc excle表格功能编写
     **/
    @RestController
    @RequestMapping("/excel")
    public class ExcelController {
    
        @Autowired
        private ExcelService excelService;
    
        /**
         * 下载文件
         *
         * @return
         */
        @RequestMapping({"/download"})
        public void download() {
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletResponse response = requestAttributes.getResponse();
            HttpServletRequest request = requestAttributes.getRequest();
    
            // 文件名
            String filename = "地址列表.xls";
            OutputStream out = null;
            try {
           // 下面几行是为了解决文件名乱码的问题
                httpServletResponse.setHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes(), "iso-8859-1"));
                httpServletResponse.setContentType("application/vnd.ms-excel;charset=UTF-8");
                httpServletResponse.setHeader("Pragma", "no-cache");
                httpServletResponse.setHeader("Cache-Control", "no-cache");
                httpServletResponse.setDateHeader("Expires", 0);
                out = httpServletResponse.getOutputStream();
                // 创建写工作簿对象,这里直接采用流输出,而不会再生成一个文件
                WritableWorkbook workbook = Workbook.createWorkbook(out);
                // 工作表
                WritableSheet sheet = workbook.createSheet("地址列表", 0);
                // 设置字体;
                WritableFont font = new WritableFont(WritableFont.ARIAL, 14, WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK);
    
                WritableCellFormat cellFormat = new WritableCellFormat(font);
                // 设置背景颜色;
                cellFormat.setBackground(Colour.WHITE);
                // 设置边框;
                cellFormat.setBorder(Border.ALL, BorderLineStyle.DASH_DOT);
                // 设置文字居中对齐方式;
                cellFormat.setAlignment(Alignment.CENTRE);
                // 设置垂直居中;
                cellFormat.setVerticalAlignment(VerticalAlignment.CENTRE);
                // 分别给1,5,6列设置不同的宽度;
                sheet.setColumnView(0, 15);
                sheet.setColumnView(4, 60);
                sheet.setColumnView(5, 35);
                // 给sheet电子版中所有的列设置默认的列的宽度;
                sheet.getSettings().setDefaultColumnWidth(20);
                // 给sheet电子版中所有的行设置默认的高度,高度的单位是1/20个像素点,但设置这个貌似就不能自动换行了
                // sheet.getSettings().setDefaultRowHeight(30 * 20);
                // 设置自动换行;
                cellFormat.setWrap(true);
    
                // 单元格
                Label label0 = new Label(0, 0, "ID", cellFormat);
                Label label1 = new Label(1, 0, "省", cellFormat);
                Label label2 = new Label(2, 0, "市", cellFormat);
                Label label3 = new Label(3, 0, "区", cellFormat);
                Label label4 = new Label(4, 0, "详细地址", cellFormat);
                Label label5 = new Label(5, 0, "创建时间", cellFormat);
    
                sheet.addCell(label0);
                sheet.addCell(label1);
                sheet.addCell(label2);
                sheet.addCell(label3);
                sheet.addCell(label4);
                sheet.addCell(label5);
    
                // 给第二行设置背景、字体颜色、对齐方式等等;
                WritableFont font2 = new WritableFont(WritableFont.ARIAL, 14, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK);
                WritableCellFormat cellFormat2 = new WritableCellFormat(font2);
                // 设置文字居中对齐方式;
                cellFormat2.setAlignment(Alignment.CENTRE);
                // 设置垂直居中;
                cellFormat2.setVerticalAlignment(VerticalAlignment.CENTRE);
                cellFormat2.setBackground(Colour.WHITE);
                cellFormat2.setBorder(Border.ALL, BorderLineStyle.THIN);
                cellFormat2.setWrap(true);
    
                // 记录行数
                int n = 1;
    
                // 查找所有地址
                List<Address> addressList = excelService.findAll();
                if (addressList != null && addressList.size() > 0) {
    
                    // 遍历
                    for (Address a : addressList) {
    
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        String createTime = sdf.format(a.getCreateTime());
    
                        Label lt0 = new Label(0, n, a.getId() + "", cellFormat2);
                        Label lt1 = new Label(1, n, a.getProvince(), cellFormat2);
                        Label lt2 = new Label(2, n, a.getCity(), cellFormat2);
                        Label lt3 = new Label(3, n, a.getArea(), cellFormat2);
                        Label lt4 = new Label(4, n, a.getAddress(), cellFormat2);
                        Label lt5 = new Label(5, n, createTime, cellFormat2);
    
                        sheet.addCell(lt0);
                        sheet.addCell(lt1);
                        sheet.addCell(lt2);
                        sheet.addCell(lt3);
                        sheet.addCell(lt4);
                        sheet.addCell(lt5);
    
                        n++;
                    }
                }
    
                //开始执行写入操作
                workbook.write();
                //关闭流
                workbook.close();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }    

      上面的代码就是关键的文件,至于一些其它的配置,以及可用的demo,可在前一篇文章 《超详细的java生成excel文件并下载》 上下载下来稍稍一下。

  • 相关阅读:
    P1182 数列分段`Section II`
    算法整理:Floyd_多源最短路
    【FBI WARNING】递归(高级数据结构的基础)
    【FBI WARNING】DP 从看透到看开
    两个例题
    结构体
    环状序列(Circular Sequence, ACM/ICPC Seoul 2004, UVa1584)
    生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)
    猜数字游戏的提示(Master-Mind Hints, UVa 340)
    回文词(Palindromes, UVa401)
  • 原文地址:https://www.cnblogs.com/dyh2025/p/9966793.html
Copyright © 2020-2023  润新知