前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 操作 Office:POI之word图片处理

Java 操作 Office:POI之word图片处理

作者头像
程序员架构进阶
发布2021-08-23 13:51:37
1.5K0
发布2021-08-23 13:51:37
举报
文章被收录于专栏:架构进阶架构进阶

一 背景问题

本系列旨在分享一些word操作框架POI的一些使用技巧,系统学习可直接参考官方文档,或上一篇中提到的Apache POI Word(docx) 入门示例教程。更多交流可添加公众号【程序员架构进阶】一起探讨。

本篇是根据一个真实场景,探索的实现方法。我们有一些希望插入word的图片,在插入时也要对图片本身添加一些标注,例如红框标记等等,也可能是添加文字标注。如果是手工操作,这显然比较简单,使用美图秀秀、Photoshop等工具,或只是截图工具中直接划线、添加文字就可以快速实现。但当需要处理的是批量数据,手工方式就不适合了。

二 一个简单的想法

因为最终是要写入word,所以暂时考虑还是使用XWPFRun.addPicture方法在单元格插入图片。但下一步,我们要在执行插入前,对图片做完所需的处理动作。这里可以考虑ImageIO 和 Graphics,这两个Java中的图片图形处理工具类来实现了。

三 Graphics

3.1 简介

java.awt.Graphics是一个抽象类,根据源码中的文档描述,

Graphics类是所有图形上下文的抽象基类,允许应用程序绘制在各种设备上实现的组件以及屏幕外图像上。

Graphics的使用已经被很多人整理过,所以本篇就不再赘述。可以参考文章:Java Graphics类的绘图方法了解完整的使用方法。这里只抽取所需的方法介绍,并给出示例。

3.2 矩形绘制

在图片中绘制一个矩形,来代表框选区域,通过配合颜色选择(红橙黄),可以起到标示作用。矩形区域,我们按照从左到右的方向,可以简单用起点横坐标:x,起点纵坐标:y,以及宽度width+高度height来确定。当然,其实宽度和高度也可以替换终点横坐标 和 终点纵坐标来标示。

在Graphics中绘制矩形的方法:

public void drawRect(int x, int y, int width, int height)

3.3 多边形绘制

矩形只有四个点,显示中可能需要绘制复杂的多边形,那么上述方法就无法满足了。所以Graphics提供了一个更为通用的绘制多边形方法:

public abstract void drawPolygon(int xPoints[], int yPoints[],
                                     int nPoints);

参数的xPoints,yPoints,nPoints分别代表横坐标数组,纵坐标数组,线段个数;xPoints和yPoints大小必须相同。

这个方法会绘制由 nPoint 个线段定义的多边形,其中前 nPoint - 1 个线段是 1 ≤ i ≤ 时从 (xPoints[i - 1], yPoints[i - 1]) 到 (xPoints[i], yPoints[i]) 的线段。如果最后一个点和第一个点不同,则图形会通过在这两点间绘制一条线段来自动闭合。

除了直接输入坐标,也可以通过传入定义的Polygon类来进行封装,使用drawPolygon(Polygon p)实现绘制:

public void drawPolygon(Polygon p) {
        drawPolygon(p.xpoints, p.ypoints, p.npoints);
    }

3.4 实现示例

/**
* 添加多边形
* @param imgFile
* @return
* @throws Exception
*/
public static BufferedImage addPolygon(String imgFile) throws Exception {
        BufferedImage image = ImageIO.read(new File(imgFile));
        Graphics g = image.getGraphics();

        int px2[]={100,480,470,480,240,100,110,100};
        int py2[]={155,175,185,395,315,185,175,155};

        g.setColor(Color.red);
        g.drawPolygon(px2,py2,8);

        return image;
}

四 处理结果写入word

4.1 参数转换

接下来回到另一个关键问题:图片处理结果怎样写入word?先回顾一下上一篇的内容:

run.addPicture 接收的参数依次为:图片的 InputStream 流,图片类型,图片名称(非文件名),图片宽度、图片高度。通过这个方法,我们就可以把图片插入到指定的表格中,并设置图片的宽高属性。

对于图片输入,addPicture要求的参数是InputStream,而我们上面的图片处理结果,是BufferedImage。显然是无法直接插入到word的Cell中的。那么该怎么办?两种方法,要么另寻出路,看是否有图片处理完成的结果是InputStream;要么就是想办法把BufferedImage转成InputStream。

写到这里,我想起了一句话:『当手里有锤子,看什么都像钉子』。这句话本来是说容易养成思维定势,但在现实中,如果我们看到的东西限制在某些场景,例如金属制品,那么当我们的需求是把其他东西固定住时,考虑用手中的锤子把已有的材料加工成钉子来达到目的也未尝不可,尽管可能不是最佳的方法。当然,这种尝试并不是盲目的,而是在目标明确,且对材料和手中的工具有一定了解的情况下。

话说回来,BufferedImage本身也是一种流的结构,那么就存在着转为ImputStream的可能。

4.2 代码实现与示例

将BufferedImage转换为InputStream,亲测可用 这篇文章就给出了解决方法,所以采用了这段代码加以实现:

/**
 * 将BufferedImage转换为InputStream
 * @param image
 * @return
 */
public static InputStream bufferedImageToInputStream(BufferedImage image){
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    try {
        ImageIO.write(image, "png", os);
        InputStream input = new ByteArrayInputStream(os.toByteArray());
        return input;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

通过这种方式,结合Graphics对图片的处理,得到的word导出结果如下图所示:

五 总结

在日常开发中,经常会遇到各种问题。排除不合理需求,解决困难的技术问题,保证项目的按时保质完成也是我们作为开发者的几项重要职责。在解决问题的过程中,明确目标、识别关键问题、搜索能力、问题拆解和解决能力都很重要。所谓的『经验』,就是在日常大大小小的考验过后沉淀下来的各项能力,而不只是经历。这点需要特别注意,与大家共勉。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员架构进阶 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 背景问题
  • 二 一个简单的想法
  • 三 Graphics
    • 3.1 简介
      • 3.2 矩形绘制
        • 3.3 多边形绘制
          • 3.4 实现示例
          • 四 处理结果写入word
            • 4.1 参数转换
              • 4.2 代码实现与示例
              • 五 总结
              相关产品与服务
              图片处理
              图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档