JAVA:利用Apache poi在服务器传输带有数据和图片的excel的数据流至浏览器供其下载至本地

如题,编程语言为java,利用Apache poi在服务器端生成带有数据和图片的excel的数据流至浏览器供其下载至本地,基本就是类似一个网站的数据导出功能。
主要参考网址:http://blog.csdn.net/sinat_22767969/article/details/50644648
基本主要代码是参考以上的网址的,本人在此基础上做了一些小的修改,就是使导出的图片呈比例的展示以及我本身的图片是从ftp上获取下来的,因此在插入的时候转换成字节流插入就好,还有就是自己根据自己所需生成表格的格式做些修改,这个就不明讲,自己看代码就好
先说步骤:
1、把自己所要生成excel表格的数据统一存放进List表中,我这边是放一个实体类
2、在前端请求导出数据的时候, 再用自己已经生成号的List表数据去调用生成excel表格数据流传输至前方即可
3、前端最好用GET请求后台,这样前端可以直接调用后台该接口即可在浏览器完成下载,至于POST方法,本人没试成功,具体原因也不清楚。。。。
废话少说,show you code:
(1)设置excel的类

import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import cn.recour.wiicop.db.entity.JYZTVio;//需要导出数据的实体类

/** 
 *  
 * @类名: ExportToExcelUtil 
 * @描述: 设置excel'的信息 
 * 
 */  
public class ExportToExcelUtil {  
    public static void out(HttpServletResponse response, List<JYZTVio> list,String fileName)  
            throws Exception {  
        /** 
         * 指定下载名 
         */  
//        String fileName = "违停拍数据.xls";  
        /** 
         * 编码 
         */  
        fileName = new String(fileName.getBytes("UTF-8"), "UTF-8");
        /** 
         * 去除空白行 
         */  
        response.reset();  
        /** 
         * 指定下载的文件名与设置相应头 
         */ 
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition", "attachment;filename="  
                + fileName);  
        /** 
         * 下载文件类型 
         */  
        response.setContentType("application/vnd.ms-excel");  
        /** 
         * 别给我缓存 
         */  
        response.setHeader("Pragma", "no-cache");  
        response.setHeader("Cache-Control", "no-cache");  
        response.setDateHeader("Expires", 0);  
        /** 
         * 得到输出流,放到缓冲区  
         */  
        OutputStream output = response.getOutputStream();  
        BufferedOutputStream bufferedOutPut = new BufferedOutputStream(output);  

        /** 
         * 下面是导出的excel格式的设置 
         */  
        /*******************我是分割线**************************************/  


        // 定义单元格报头  
        String worksheetTitle = "违停拍数据";  

        HSSFWorkbook wb = new HSSFWorkbook();  

        // 创建单元格样式  
        HSSFCellStyle cellStyleTitle = wb.createCellStyle();  
        // 指定单元格居中对齐  
        cellStyleTitle.setAlignment(HSSFCellStyle.ALIGN_CENTER);  
        // 指定单元格垂直居中对齐  
        cellStyleTitle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);  
        // 指定当单元格内容显示不下时自动换行  
        cellStyleTitle.setWrapText(true);  
        HSSFCellStyle cellStyle = wb.createCellStyle();  
        // 指定单元格居中对齐  
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);  
        // 指定单元格垂直居中对齐  
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);  
        // 指定当单元格内容显示不下时自动换行  
        cellStyle.setWrapText(true);  
        // 设置单元格字体  
        HSSFFont font = wb.createFont();  
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);  
        font.setFontName("宋体");  
        font.setFontHeight((short) 200);  
        cellStyleTitle.setFont(font);  

        /****************wo是分割线*****************************************/  

        /** 
         * 工作表列名 
         */  
        String id = "序号";  
        String cphm = "车牌号码";  
        String location = "违停地址";
        String time = "违停时间";
        String img = "违停照片";


        HSSFSheet sheet = wb.createSheet();  
        ExportExcelUtil exportExcel = new ExportExcelUtil(wb, sheet);  
        /** 
         * 创建报表头部 
         */  
        exportExcel.createNormalHead(worksheetTitle, 4);  
        // 定义第一行  
        HSSFRow row1 = sheet.createRow(1);  
        HSSFCell cell1 = row1.createCell(0);  

        /** 
         * 第一行第一列 
         */  

        cell1.setCellStyle(cellStyleTitle);  
        cell1.setCellValue(new HSSFRichTextString(id));  
        /** 
         * 第一行第二列 
         */  
        cell1 = row1.createCell(1);  
        cell1.setCellStyle(cellStyleTitle);  
        cell1.setCellValue(new HSSFRichTextString(cphm));  

        /** 
         * 第一行第三列 
         */  
        cell1 = row1.createCell(2);  
        cell1.setCellStyle(cellStyleTitle);  
        cell1.setCellValue(new HSSFRichTextString(location));  

        /** 
         * 第一行第四列 
         */  
        cell1 = row1.createCell(3);  
        cell1.setCellStyle(cellStyleTitle);  
        cell1.setCellValue(new HSSFRichTextString(time));  

        /** 
         * 第一行第五列 
         */  
        cell1 = row1.createCell(4);  
        cell1.setCellStyle(cellStyleTitle);  
        cell1.setCellValue(new HSSFRichTextString(img));  
        /********************我是分割线*********************************/  

        /** 
         * 定义第二行,就是我们的数据 
         */  
        HSSFRow row = sheet.createRow(2);  
        HSSFCell cell = row.createCell(1);  
        sheet.setColumnWidth(4, 30 * 256);//固定图片宽度大小为30*256,然后在下面设置图片以此宽度为基准设置高度
        /** 
         * 遍历我们传进来的jyztVio-list 
         */  
        JYZTVio jyztVio =null;  
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();  

        for (int i = 0; i < list.size(); i++) {  
            jyztVio = list.get(i);  
            /** 
             * 从i+2行开始,因为我们之前的表的标题和列的标题已经占用了两行 
             */  
            row = sheet.createRow(i + 2);  
            int s = i+1;  
            //...id  
            cell = row.createCell(0);  
            cell.setCellStyle(cellStyle);  
            cell.setCellValue(new HSSFRichTextString(s + ""));  
            //....车牌号码cphm  
            cell = row.createCell(1);  
            cell.setCellStyle(cellStyle);  
            cell.setCellValue(new HSSFRichTextString("\n"+jyztVio.getCphm()+"\n"));  
            //....违停地址  
            cell = row.createCell(2);  
            cell.setCellStyle(cellStyle);  
            cell.setCellValue(new HSSFRichTextString("\n"+jyztVio.getLocation()+"\n"));
            //....违停时间  
            cell = row.createCell(3);  
            cell.setCellStyle(cellStyle);  
            cell.setCellValue(new HSSFRichTextString("\n"+jyztVio.getTime()+"\n"));
            //...违停拍照  
            short h =2;//定义图片所在行  
            short l=4;//定义图片所在列  
            cell = row.createCell(4);  
            cell.setCellStyle(cellStyle);  
            //得到图片  new FileUtils().getFile(String path)这是我从ftp上获取图片的方法,里面参数是图片路径,各位具体情况具体处理
            InputStream sbs = new ByteArrayInputStream(new FileUtils().getFile(jyztVio.getImage()));
            BufferedImage image = ImageIO.read(sbs);
            ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();  
            int width = image.getWidth();//图片原始宽度
            int height = image.getHeight();//图片原始高度
            //根据宽度按比例设置高度
            height = (int) Math.round((height * (30 * 13) * 1.0 / width));
            row.setHeight((short) (height / 2 * 20));
            ImageIO.write(image, "jpg", byteArrayOut);  
            HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, l, i + h, (short) (l+1), (i+1) + h);  
            anchor.setAnchorType(3); 

            // 插入图片  
            patriarch.createPicture(anchor, wb.addPicture(  
                    byteArrayOut.toByteArray(),  
                    HSSFWorkbook.PICTURE_TYPE_JPEG));  

        }  
        try {  
            /** 
             * 输出到浏览器
             */  
            bufferedOutPut.flush();  
            wb.write(bufferedOutPut);  
            bufferedOutPut.close();//关流  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            list.clear();  
        }  
    }  
}  

(2)excel导出的工具类

/**
 * @author czy
 * @version 创建时间:2017年10月31日 下午5:37:17
 * 
 */
import java.io.File;  
import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;  

import org.apache.poi.hssf.usermodel.HSSFCell;  
import org.apache.poi.hssf.usermodel.HSSFCellStyle;  
import org.apache.poi.hssf.usermodel.HSSFFont;  
import org.apache.poi.hssf.usermodel.HSSFRichTextString;  
import org.apache.poi.hssf.usermodel.HSSFRow;  
import org.apache.poi.hssf.usermodel.HSSFSheet;  
import org.apache.poi.hssf.usermodel.HSSFWorkbook;  
import org.apache.poi.hssf.util.HSSFColor;  
import org.apache.poi.hssf.util.Region;  

/** 
 *  
 * @类名: ExportExcel 
 * @描述: excel工具类 
 *  
 */  
public class ExportExcelUtil {  

    private HSSFWorkbook wb = null;  
    private HSSFSheet sheet = null;  

    /** 
     *  
     * <p> 
     * 标题: 
     * </p> 
     * <p> 
     * 描述: 
     * </p> 
     *  
     * @param wb 
     * @param sheet 
     */  
    public ExportExcelUtil(HSSFWorkbook wb, HSSFSheet sheet) {  
        // super();  
        this.wb = wb;  
        this.sheet = sheet;  
    }  

    /** 
     *  
     * @标题: createNormalHead 
     * @描述: TODO(这里用一句话描述这个方法的作用) 
     * @参数: @param headString 头部的字符 
     * @参数: @param colSum 报表的列数 
     * @返回: void 返回类型 
     * @抛出: 
     */  
    @SuppressWarnings("deprecation")  
    public void createNormalHead(String headString, int colSum) {  
        HSSFRow row = sheet.createRow(0);  
        // 设置第一行  
        HSSFCell cell = row.createCell(0);  
        // row.setHeight((short) 1000);  

        // 定义单元格为字符串类型  
        cell.setCellType(HSSFCell.ENCODING_UTF_16);// 中文处理  
        cell.setCellValue(new HSSFRichTextString(headString));  

        // 指定合并区域  
        /** 
         * public Region(int rowFrom, short colFrom, int rowTo, short colTo) 
         */  
        sheet.addMergedRegion(new Region(0, (short) 0, 0, (short) colSum));  

        // 定义单元格格式,添加单元格表样式,并添加到工作簿  
        HSSFCellStyle cellStyle = wb.createCellStyle();  
        // 设置单元格水平对齐类型  
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐  
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐  
        cellStyle.setWrapText(true);// 指定单元格自动换行  

        // 设置单元格字体  
        HSSFFont font = wb.createFont();  
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);  
        font.setFontName("宋体");  
        font.setFontHeight((short) 600);  
        cellStyle.setFont(font);  
        cell.setCellStyle(cellStyle);  
    }  

    /** 
     *  
     * @标题: createNormalTwoRow  
     * @描述: 创建通用报表第二行 
     * @参数: @param params 二行统计条件数组 
     * @参数: @param colSum 需要合并到的列索引 
     * @返回: void    返回类型  
     * @抛出: 
     */  
    @SuppressWarnings("deprecation")  
    public void createNormalTwoRow(String[] params, int colSum) {  
        // 创建第二行  
        HSSFRow row1 = sheet.createRow(1);  

        row1.setHeight((short) 400);  

        HSSFCell cell2 = row1.createCell(0);  

        cell2.setCellType(HSSFCell.ENCODING_UTF_16);  
        cell2.setCellValue(new HSSFRichTextString("时间:" + params[0] + "至"  
                + params[1]));  

        // 指定合并区域  
        sheet.addMergedRegion(new Region(1, (short) 0, 1, (short) colSum));  

        HSSFCellStyle cellStyle = wb.createCellStyle();  
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐  
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐  
        cellStyle.setWrapText(true);// 指定单元格自动换行  

        // 设置单元格字体  
        HSSFFont font = wb.createFont();  
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);  
        font.setFontName("宋体");  
        font.setFontHeight((short) 250);  
        cellStyle.setFont(font);  

        cell2.setCellStyle(cellStyle);  
    }  

    /** 
     *  
     * @标题: createColumHeader  
     * @描述: 设置报表标题  
     * @参数: @param columHeader    标题字符串数组 
     * @返回: void    返回类型  
     * @抛出: 
     */  
    public void createColumHeader(String[] columHeader) {  

        // 设置列头 在第三行    
        HSSFRow row2 = sheet.createRow(2);  

        // 指定行高  
        row2.setHeight((short) 600);  

        HSSFCellStyle cellStyle = wb.createCellStyle();  
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐  
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐  
        cellStyle.setWrapText(true);// 指定单元格自动换行  

        // 单元格字体  
        HSSFFont font = wb.createFont();  
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);  
        font.setFontName("宋体");  
        font.setFontHeight((short) 250);  
        cellStyle.setFont(font);  

        // 设置单元格背景色  
        cellStyle.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);  
        cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);  

        HSSFCell cell3 = null;  

        for (int i = 0; i < columHeader.length; i++) {  
            cell3 = row2.createCell(i);  
            cell3.setCellType(HSSFCell.ENCODING_UTF_16);  
            cell3.setCellStyle(cellStyle);  
            cell3.setCellValue(new HSSFRichTextString(columHeader[i]));  
        }  
    }  
    /** 
     *  
     * @标题: cteateCell  
     * @描述: 创建内容单元格 
     * @参数: @param wb HSSFWorkbook 
     * @参数: @param row HSSFRow 
     * @参数: @param col short型的列索引 
     * @参数: @param align 对齐方式 
     * @参数: @param val   列 
     * @返回: void    返回类型  
     * @抛出: 
     */  
    public void cteateCell(HSSFWorkbook wb, HSSFRow row, int col, short align,  
            String val) {  
        HSSFCell cell = row.createCell(col);  
        cell.setCellType(HSSFCell.ENCODING_UTF_16);  
        cell.setCellValue(new HSSFRichTextString(val));  
        HSSFCellStyle cellstyle = wb.createCellStyle();  
        cellstyle.setAlignment(align);  
        cell.setCellStyle(cellstyle);  
    }  

    /** 
     *  
     * @标题: createLastSumRow  
     * @描述: 创建合计行 
     * @参数: @param colSum 需要合并到的列索引 
     * @参数: @param cellValue    设定文件  
     * @返回: void    返回类型  
     * @抛出: 
     */  
    @SuppressWarnings("deprecation")  
    public void createLastSumRow(int colSum, String[] cellValue) {  

        HSSFCellStyle cellStyle = wb.createCellStyle();  
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐  
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐  
        cellStyle.setWrapText(true);// 指定单元格自动换行  

        // 单元格字体  
        HSSFFont font = wb.createFont();  
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);  
        font.setFontName("宋体");  
        font.setFontHeight((short) 250);  
        cellStyle.setFont(font);  
        // 获取工作表最后一行  
        HSSFRow lastRow = sheet.createRow((short) (sheet.getLastRowNum() + 1));  
        HSSFCell sumCell = lastRow.createCell(0);  

        sumCell.setCellValue(new HSSFRichTextString("合计"));  
        sumCell.setCellStyle(cellStyle);  
        // 合并 最后一行的第零列-最后一行的第一列  
        sheet.addMergedRegion(new Region(sheet.getLastRowNum(), (short) 0,  
                sheet.getLastRowNum(), (short) colSum));// 指定合并区域  

        for (int i = 2; i < (cellValue.length + 2); i++) {  
            // 定义最后一行的第三列  
            sumCell = lastRow.createCell(i);  
            sumCell.setCellStyle(cellStyle);  
            // 定义数组 从0开始。  
            sumCell.setCellValue(new HSSFRichTextString(cellValue[i - 2]));  
        }  
    }  

    /** 
     *  
     * @标题: outputExcel  
     * @描述: 输出excel下载 
     * @参数: @param fileName    文件名  
     * @返回: void    返回类型  
     * @抛出: 
     */  
    public void outputExcel(String fileName) {  
        FileOutputStream fos = null;  
        try {  
            fos = new FileOutputStream(new File(fileName));  
            wb.write(fos);  
            fos.close();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  

    /** 
     *  
     * @返回: HSSFSheet    返回类型  
     */  
    public HSSFSheet getSheet() {  
        return sheet;  
    }  

    public void setSheet(HSSFSheet sheet) {  
        this.sheet = sheet;  
    }  

    /** 
     *  
     * @返回: HSSFWorkbook    返回类型  
     */  
    public HSSFWorkbook getWb() {  
        return wb;  
    }  

    /** 
     *  
     */  
    public void setWb(HSSFWorkbook wb) {  
        this.wb = wb;  
    }  
}  

Controller层的代码:

/**
     * 下载违停拍数据
     * @param body
     * @param request
     * @param response
     */
    @RequestMapping(value = "/downloaddata", method = RequestMethod.GET)
    public @ResponseBody void downloaddata(HttpServletRequest request,HttpServletResponse response){
        try {
            String fileName = request.getParameter("fileName");
            List<JYZTVio> jyztViolist = jyztVioService.downloaddata(request,response);
            if(jyztViolist==null){
                preJson(response,"无下载内容");
            }else{
                ExportToExcelUtil.out(response, jyztViolist, fileName);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

这样,前端只要调用该接口,就可以在浏览器完成下载功能。
注意:本人以上生成excel表和Excel工具类的代码基本是借鉴以上网址而来,只是根据自己功能需求做了一些改变,并没有想拿来做商业用途,如需要可删!
主要参考网址:http://blog.csdn.net/sinat_22767969/article/details/50644648

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值