POI XSSFWorkbook读取网络中的图片资源导入EXCEL中

POI XSSFWorkbook读取网络中的图片资源导入EXCEL中


摘要

Poi导出Excel有多种java类可以实现,但实现的原理几乎都是相同的:
1.创建工作博 2.创建sheet 3.创建行(row) 4.创建cell单元格 5.将数据加入单元格。下面是总结的代码。

代码结构

  • 导出方法:
    • public static void exportExcelImg(HttpServletResponse response, String fileName, ExcelData data) throws Exception {}
  • 封装实体类:
    • public class ExcelData implements Serializable{}

代码

ExcelData:用来封装导出数据的实体类
用来封装导出数据的实体类

exportExcelImg(…):导出方法

//导出带有图片的excel
    public  static void exportExcelImg(HttpServletResponse response, String fileName,
                                       ExcelData data)  throws Exception {
        FileOutputStream fileOut = null;
        BufferedImage bufferImg = null;//logo
        ByteArrayOutputStream byteArrayOut = null; //读进图片
        HttpURLConnection conn =null;

        response.setHeader("content-Type", "application/vnd.ms-excel");// 告诉浏览器用什么软件可以打开此文件
        response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(fileName, "utf-8"));

        XSSFWorkbook wb = new XSSFWorkbook();
        try {
            String sheetName = data.getName();
            if (null == sheetName) {
                sheetName = "Sheet1";
            }
            XSSFSheet sheet = wb.createSheet(sheetName);

            int width = 25;
            sheet.setColumnWidth(0, 256*width+100);//列宽
            sheet.setColumnWidth(1, 256*width+100);
            sheet.setColumnWidth(2, 256*width+100);

            XSSFDrawing patriarch = sheet.createDrawingPatriarch();

            //导出标题
            int rowIndex = 0;
            rowIndex = writeTitlesToExcel(wb, sheet, data.getTitles());

            //字体样式
            int colIndex = 0;
            Font dataFont = wb.createFont();
            dataFont.setFontName("simsun");
            dataFont.setColor(IndexedColors.BLACK.index);

            //设置单元格类型
            XSSFCellStyle cellStyle = wb.createCellStyle();
            cellStyle.setFont(dataFont);
            cellStyle.setAlignment(cellStyle.getAlignmentEnum().CENTER);//水平居中
            cellStyle.setWrapText(true);//自动换行

            //遍历每行, 遍历单元格
            for (List<Object> rowData : data.getRows()) {
                Row dataRow = sheet.createRow(rowIndex);
                dataRow.setHeight((short)(256*15));//设置行高
                colIndex = 0;

                for (Object cellData : rowData) {
                    Cell cell = dataRow.createCell(colIndex);
                    if (cellData != null) {
                        if(0 == colIndex){
                            //第二列为logo,导出图片

                            byteArrayOut = new ByteArrayOutputStream();
                            String pictureUrl = cellData.toString();
                            if(StringUtils.isNotBlank(pictureUrl)) {
                                URL url = new URL(pictureUrl);
                                //打开链接
                                conn = (HttpURLConnection)url.openConnection();
                                //设置请求方式为"GET"
                                conn.setRequestMethod("GET");
                                //超时响应时间为50秒
                                conn.setConnectTimeout(50 * 1000);
                                //通过输入流获取图片数据
                                InputStream inStream = conn.getInputStream();
                                //得到图片的二进制数据,以二进制封装得到数据,具有通用性
                                byte[] byteData = readInputStream(inStream);

                                /**anchor主要用于设置图片的属性
                                 * 该构造函数有8个参数
                                 * 前四个参数是控制图片在单元格的位置,分别是图片距离单元格left,top,right,bottom的像素距离
                                 * 后四个参数,前两个表示图片左上角所在的cellNum和 rowNum,后两个参数对应的表示图片右下角所在的cellNum和 rowNum,
                                 * excel中的cellNum和rowNum的index都是从0开始的
                                 *
                                 */
                                XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short)colIndex, rowIndex, (short) colIndex+1,rowIndex+1 );

                                //Sets the anchor type (图片在单元格的位置)
                                //0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.

                                anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);//设置图片随单元移动调整大小

                                patriarch.createPicture(anchor, wb.addPicture(byteData, XSSFWorkbook.PICTURE_TYPE_JPEG));
                            }
                        }else {
                            cell.setCellValue(cellData.toString());
                        }
                    } else {
                        cell.setCellValue("");
                    }

                    cell.setCellStyle(cellStyle);
                    colIndex++;
                }
                rowIndex++;
            }

            //输出目的地
            wb.write(response.getOutputStream());
        } finally {
            wb.close();
            conn.disconnect();
        }

    }

    private static byte[] readInputStream(InputStream inStream) throws Exception{
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        //创建一个Buffer字符串
        byte[] buffer = new byte[1024];
        //每次读取的字符串长度,如果为-1,代表全部读取完毕
        int len = 0;
        //使用一个输入流从buffer里把数据读取出来
        while( (len=inStream.read(buffer)) != -1 ){
            //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        //关闭输入流
        inStream.close();
        //把outStream里的数据写入内存
        return outStream.toByteArray();
    }

调用导出方法代码

  • 将导出方法放到工具类中,直接调用,很方便
 ExportExcelUtils.exportExcelImg(response, "一百强企业名单.xlsx", excelData);

代码运行效果

  • 导出后我看不美观,但是经理说可以了,那就这样吧,其实还可以慢慢调整宽高,但是调着太麻烦了,不过你可以自己慢慢整(调整列宽查找XSSFSheet Api、调整行高查找Row Api)。

运行效果

猜你喜欢

转载自blog.csdn.net/fengzyf/article/details/82622409
今日推荐