• 使用ApachePOI创建带图片的Excel


      最近一个项目中使用到了列表数据导出为Excel表格的功能,项目中是使用了Apache的POI来生成Excel文件。

      由于使用到的技术有一定的复杂度,我在此特别列出一些实现上的细节作为记录和备忘。

      首先我们要用到的jar包是POI,我使用的是项目框架中的,版本可能有一些老,不过功能还算完整。

      

      我先把代码贴一些出来,并解释一下:

     1 package test;
     2 
     3 import java.awt.image.BufferedImage;
     4 import java.io.ByteArrayOutputStream;
     5 import java.io.File;
     6 import java.io.FileOutputStream;
     7 import java.net.URL;
     8 
     9 import javax.imageio.ImageIO;
    10 import javax.swing.filechooser.FileSystemView;
    11 
    12 import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
    13 import org.apache.poi.hssf.usermodel.HSSFPatriarch;
    14 import org.apache.poi.hssf.usermodel.HSSFSheet;
    15 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    16 
    17 // 测试Apache POI
    18 public class Main{
    19     public static void main(String[] args){
    20         // 第一步:拿到图片资源
    21         BufferedImage bi = null; // 声明图片
    22         // 1.从网络获取图片资源(下面的图片为百度首页图片)
    23         //URL url = new URL("http://www.baidu.com/img/shouye_b5486898c692066bd2cbaeda86d74448.gif");
    24         //bi = ImageIO.read(url);
    25         // 2.从物理存储设备获取图片资源(以下示例为从笔者桌面获取图片)
    26         File f = new File(FileSystemView.getFileSystemView().getHomeDirectory() + "/baidu.gif");
    27         bi = ImageIO.read(f);
    28         
    29         // 第二步:处理图片(很多时候失败原因就是没有处理图片)
    30         ByteArrayOutputStream bos = new ByteArrayOutputStream();
    31         ImageIO.write(bi, "jpg", bos);
    32         
    33         // 第三步:创建Excel并插入图片(这里就要使用POI了)
    34         HSSFWorkbook wb = new HSSFWorkbook(); // 创建一个工作簿
    35         HSSFSheet sheet = wb.createSheet("Sample"); // 创建一个床单-_-
    36         HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); // 创建一个用于画图的对象
    37         // 以上部分为共用,表单Sample中所有图片的操作都应该有patriarch负责
    38         HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short)0, 0, (short)1, 1); // 创建一个图片停靠信息对象
    39         // anchor.setAnchorType(2); 设置这个属性是为哪个图片设置的,第一张图片不需要设置
    40         patriarch.createPicture(anchor, wb.addPicture(bos.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG)); // 这一步就是按照上面的属性将图片插入到床单Sample中去
    41         
    42         // 第四步:我们保存(或下载)生成的Excel(笔者保存到桌面)
    43         File fo = new File(FileSystemView.getFileSystemView().getHomeDirectory() + "/sample.xls");
    44         FileOutputStream fos = null;
    45         fos = new FileOutputStream(fo);
    46         wb.write(fos);
    47         fos.flush();
    48         fos.close();
    49     }
    50 }

      

      (上图异常未处理,因为最终我们需要将代码写得更规范,异常的处理也要更加好,上图只做参考)

      我稍微解释一下,首先图片的获得一般为两种途径,网络和磁盘。我们拿到图片后的处理是必须的,因为大家可以看到,POI对图片的支持和解析并不是那么强大,我们需要使用ImageIO来提取图片的内容,并使用jpg格式写入缓冲来交给POI使用。

      其次就是图片在Excel中的放置,顺便提一下Anchor的各个参数,为了方便大家理解,我先将代码运行结果贴出来给大家: 

      

      可以看到,在坐上角为0,0 右下角为1,1的网格中出现了图片,这解释了anchor的后四个参数,即图片左上角和右下角的坐标,至于为什么x坐标为short,不会不知道吧?

      (所以我们没有在sheet里创建row和column来放置图片,因为在office套件里图片和文字并不是放置在一个平面的,可以这么理解:文字是放置在行、列中的格子里,而图片是沉浮在网格中的)

      那么anchor的前四个参数是什么呢?其实Excel为了图片停靠地更加精细,将一个格子分成了1024x256个小格子,我们可以为图片设置它相对于左上角、右下角的横向和纵向偏移量(0-1023或0-255),看了下图大家就明白了:

      

      (上图为anchor前四个参数设置为512,126,0,0)

      

      (上图为anchor前四个参数设置为0,0,512,126)

      

      (毋庸置疑,上图为anchor四个参数设置为512,126,512,126)

      可以通过sheet.setColumWidth和row.setHeight设置列宽和行高。

      贴上我的代码:

     1 package test;
     2 
     3 import java.awt.image.BufferedImage;
     4 import java.io.ByteArrayOutputStream;
     5 import java.io.File;
     6 import java.io.FileNotFoundException;
     7 import java.io.FileOutputStream;
     8 import java.io.IOException;
     9 import java.net.MalformedURLException;
    10 import java.net.URL;
    11 
    12 import javax.imageio.ImageIO;
    13 import javax.swing.filechooser.FileSystemView;
    14 
    15 import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
    16 import org.apache.poi.hssf.usermodel.HSSFPatriarch;
    17 import org.apache.poi.hssf.usermodel.HSSFSheet;
    18 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    19 
    20 // 测试Apache POI
    21 public class Main {
    22     public static void main(String[] args) {
    23         BufferedImage bi = null; 
    24         ByteArrayOutputStream bos = new ByteArrayOutputStream();
    25         HSSFWorkbook wb = new HSSFWorkbook();
    26         HSSFSheet sheet = wb.createSheet("Sample");
    27         HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
    28         FileOutputStream fos = null;
    29         
    30         try {
    31             URL url = new URL("http://www.baidu.com/img/shouye_b5486898c692066bd2cbaeda86d74448.gif");
    32             bi = ImageIO.read(url);
    33 
    34             //File f = new File(FileSystemView.getFileSystemView().getHomeDirectory() + "/baidu.gif");
    35             //bi = ImageIO.read(f);
    36             
    37             ImageIO.write(bi, "jpg", bos);
    38             HSSFClientAnchor anchor = new HSSFClientAnchor(512, 126, 512, 126, (short) 0,
    39                     0, (short) 1, 1);
    40             // anchor.setAnchorType(2);
    41             patriarch.createPicture(anchor,wb.addPicture(bos.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
    42             
    43             File fo = new File(FileSystemView.getFileSystemView()
    44                     .getHomeDirectory() + "/sample.xls");
    45             fos = new FileOutputStream(fo);
    46             wb.write(fos);
    47             fos.flush();
    48             fos.close();
    49             
    50             
    51         } catch (MalformedURLException e) {
    52             // TODO Auto-generated catch block
    53             e.printStackTrace();
    54         } catch (FileNotFoundException e) {
    55             // TODO Auto-generated catch block
    56             e.printStackTrace();
    57         } catch (IOException e) {
    58             // TODO Auto-generated catch block
    59             e.printStackTrace();
    60         }
    61     }
    62 }

      注意:ByteArrayOutputStream与HSSFClientAnchor是一次性用品,需要在真正使用前声明,后释放(上图是一个不正规的示范,很明显,在多个图片后bos会溢出)。

        anchorType从2开始,1不需要设置。

        有关生成的xls从服务器下载到客户端,以后再讨论。

     欢迎您移步我们的交流群,无聊的时候大家一起打发时间:Programmer Union

     或者通过QQ与我联系:点击这里给我发消息

     (最后编辑时间2013-03-27 13:46:00)

  • 相关阅读:
    atitit.无为而治在企业管理,国家治理,教育领域的具体思想与实践
    atitit.浏览器web gui操作类库 和 操作chrome浏览器的类库使用总结
    atitit.loading的设计与实现控件选型attilax 总结
    atitit.系统托盘图标的设计java swing c# .net c++ js
    atitit.流程标准化 mysql启动不起来的排查流程attilax总结
    atitit.图片相似度与图片查找的设计 获取图片指纹
    atitit.it企业管理 项目管理 中的 授权机制 的来源 君权神授 的一定合理性
    atitit..国富论 在现代it企业项目管理中的作用attialx 总结国富论读后感 attialx
    atitit.印度教与java宗教的特点与观念对比 attilax总结
    atitit.验证码识别step2剪贴板ClipBoard copy image图像 attilax总结
  • 原文地址:https://www.cnblogs.com/Johness/p/2983584.html
Copyright © 2020-2023  润新知