使用ApachePOI创建带图片的Excel

摘要:
最近的一个项目使用了将列表数据导出到Excel表的功能。该项目使用Apache POI生成Excel文件。首先,我们需要使用的jar包是POI。我在项目框架中使用它。版本可能很旧,但功能仍然完整。我们获得图片后的处理是必要的,因为您可以看到POI对图片的支持和解析并没有那么强大。我们需要使用ImageIO提取图片的内容,并使用jpg格式的写入缓冲区将其提供给POI使用。

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

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

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

  使用ApachePOI创建带图片的Excel第1张

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

 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的各个参数,为了方便大家理解,我先将代码运行结果贴出来给大家: 

  使用ApachePOI创建带图片的Excel第2张

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

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

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

  使用ApachePOI创建带图片的Excel第3张

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

  使用ApachePOI创建带图片的Excel第4张

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

  使用ApachePOI创建带图片的Excel第5张

  (毋庸置疑,上图为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)

免责声明:文章转载自《使用ApachePOI创建带图片的Excel》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇等价类划分方法的应用(二)内存泄漏解析下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

POI解析word文件,并为特定规则的key替换值

转载:https://www.aliyun.com/jiaocheng/778166.html 模板替换内容key是: ${enforcername1} package com.jsy.test.pdf; import java.io.FileOutputStream;import java.io.IOException;import java.ut...

从零搭建企业大数据分析和机器学习平台-技术栈介绍(三)

数据传输和采集 Sqoop数据传输工具实际项目开发中,往往很多业务数据是存放在关系型数据库中,如 MySQL数据库。我们需要将这些数据集中到数据仓库中进行管理,便于使用计算模型进行统计、挖掘这类操作。 Sqoop是Apache软件基金会的⼀一款顶级开源数据传输工具,用于在 Hadoop与关系型数据库(如MySQL、Oracle、PostgreSQL等)之间...

RabbitMQ、Kafka、RocketMQ的优劣势

今天我们一起来探讨:  全量的消息队列究竟有哪些?  Kafka、RocketMQ、RabbitMQ的优劣势比较  以及消息队列的选型 最全MQ消息队列有哪些 那么目前在业界有哪些比较知名的消息引擎呢?如下图所示 这里面几乎完全列举了当下比较知名的消息引擎,包括:  ZeroMQ  推特的Distributedlog  ActiveMQ:Apach...

apache配置禁止访问某些文件/目录

 我们来看俩段通常对上传目录设置无权限的列子,配置如下: 代码如下: ? 1 2 3 4 5 6 <Directory "/var/www/upload"> <FilesMatch ".php"> Order Allow,Deny Deny from all </FilesMatch> </Dir...

Spring boot + Gradle + Eclipse打war包发布总结

首先感谢两位博主的分享 http://lib.csdn.net/article/git/55444?knId=767 https://my.oschina.net/alexnine/blog/540651 buildscript { ext { springBootVersion = '1.5.2.RELEASE' }...

log4j打印不同类型的日志

介绍:在同一个项目中打印不同类型的日志 log4j.properties的配置: log=/usr/local/tomcat/logFiles log4j.rootLogger = OFF,stdout log4j.appender.stdout = org.apache.log4j.ConsoleAppenderlog4j.appender.stdout...