接上文,一封类似于下方设计的Excel报表,如何将它指定的区域导出为样式一模一样的JPG图片呢?

要实现这个功能没有现成的解决方案,谷歌度娘了好久也没有,最终自己想了几条思路:

思路1:将报表中的背景、边框等截图下来作为模型图片,需要定时更新的数据通过JDBC读取Oracle中的数据绘制到模型图片上

否定原因:不具可行性,所有数据的坐标点需要有规则方便绘图时循环绘制,工程量巨大,耦合性巨高,表格数据牵一发而动全身,并且不利于扩展。

思路2:不需要报表原型,生成Excel报表后,使用jxl或者poi一个单元一个单元读取报表内所有单元格,包括单元格的数据和格式,边框、宽度、高度、字体前景色、背景色都要读取出来,然后通过JAVA绘图,最终生成JPG格式的报表。

否定原因:具有一定的可行性,但是代码量巨大,读取和绘制费时费力,但是有一定的优点,可以在不忙的时间里编写一个通用的程序,一劳永逸的解决所有导出问题。

思路3:比较奇葩,属于博主突发奇想的招式,通过WPS或者Office打开Excel,编写Robot机器人将鼠标移动到两个指定坐标所覆盖指定区域,Robot模拟敲击Ctrl+C,接着将剪贴板上的数据绘图,导出到JPG文件。

最终实现了思路3,有一定的好处也有弊端,好处是简单便捷,可操作性高,代码量低,扩展性强,换其他报表只需要提供另一组坐标参数即可

弊端是完全牺牲了JAVA的跨平台性,甚至如果运行在分辨率较低的服务器上,有可能导致复制操作无法执行

另一个弊端是线程变得不安全了,如果服务器负载较重,无法正确预计Office打开报表的时间,也有可能导致复制操作无法执行

或者多个生成报表截图的任务同时执行时,显然使用Robot会导致冲突。

下面提供思路3的实现代码,以后有时间会使用思路2写一个通用的程序

package com.newflypig.excel;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date; import javax.imageio.ImageIO; public class OpenExcelDemo { public static void main(String[] args) throws Exception {
openExcel("d:\\新增积分月报表.xlsx"); copyRectByPix(37, 207, 1215, 665); //给定两个坐标点的数据,圈定截图范围 createImageFileFromClip("d:/" + getTimeStr() + ".jpg"); closeExcel((int)Toolkit.getDefaultToolkit().getScreenSize().getWidth() - 15, 12); //需要模拟关闭事件,将Excel关闭,以便下次能正确打开报表
} private static void closeExcel(int i, int j) throws Exception {
Robot robot = new Robot(); robot.delay(500);
robot.mouseMove(i,j);
robot.delay(500);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.delay(500);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.delay(500);
robot.keyPress(KeyEvent.VK_ENTER);
} public static void openExcel(String dir) throws Exception {
Runtime.getRuntime().exec("cmd /k " + dir + "");
} public static void copyRectByPix(int fromX, int fromY, int toX, int toY)
throws Exception {
Robot robot = new Robot();
robot.delay(3000); // 延时3000毫秒 robot.mouseMove(fromX, fromY);
robot.delay(500);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.delay(500);
robot.mouseMove(toX, toY);
robot.delay(500);
robot.mouseRelease(InputEvent.BUTTON1_MASK); robot.setAutoDelay(200);
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_C);
} public static void createImageFileFromClip(String dir) throws Exception {
Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard()
.getContents(null);
if (null != t && t.isDataFlavorSupported(DataFlavor.imageFlavor)) {
Image image = (Image) t.getTransferData(DataFlavor.imageFlavor);
savePic(image, dir);
}
} public static String savePic(Image iamge, String dir) throws Exception {
int w = iamge.getWidth(null);
int h = iamge.getHeight(null); // 首先创建一个BufferedImage变量,因为ImageIO写图片用到了BufferedImage变量。
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); // 再创建一个Graphics变量,用来画出来要保持的图片,及上面传递过来的Image变量
Graphics g = bi.getGraphics(); g.drawImage(iamge, 0, 0, null); // 将BufferedImage变量写入文件中。
ImageIO.write(bi, "jpg", new File(dir));
return dir;
} public static String getTimeStr() {
String time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
return time;
}
}

JAVA将Excel中的报表导出为图片格式(二)实现思路的更多相关文章

  1. JAVA将Excel中的报表导出为图片格式(一)问题背景

    如题所示,先抛出一个问题,如何使用JAVA将Excel中的报表导出为图片格式? 首先说一下这个问题的背景,也就是为什么博主会碰到这个问题 随着微信,易信之流大行其道,企业内部的办公交流.绩效考评甚至考 ...

  2. JAVA将Excel中的报表导出为图片格式(三)换一种实现

    上一篇介绍了使用Java的Robot机器人实现截图,然后将剪贴板上的数据流生成PNG图片 但是经过博主的不断测试,在完全依赖远程桌面的没有终端显示器的服务器上 使用截图方式是不可行的,因为一旦使用了远 ...

  3. 【转】c# winform DataGridView导出数据到Excel中,可以导出当前页和全部数据

    准备工作就是可以分页的DataGridView,和两个按钮,一个用来导出当前页数据到Excel,一个用来导出全部数据到Excel 没有使用SaveFileDialog,但却可以弹出保存对话框来 先做导 ...

  4. Java处理Excel中的日期格式

    Java处理Excel中的日期格式 2011-12-23 17:34:03|  分类: java |举报 |字号 订阅 下载LOFTER 我的照片书  |   在Excel中的日期格式,其数值为距离1 ...

  5. Java 解析Excel(xls、xlsx两种格式)

    Java 解析Excel(xls.xlsx两种格式) 一.环境 JDK 1.8 二.JAR 1.commons-collections4-4.1.jar 2.poi-3.9-20121203.jar ...

  6. java 在Excel中插入图片 POI实现

    一.POI简介 Jakarta POI 是apache的子项目,目标是处理ole2对象.它提供了一组操纵Windows文档的Java API 目前比较成熟的是HSSF接口,处理MS Excel(97- ...

  7. java程序转换excel中科学记数法的数据为date类型

    今天出于某些原因从mongodb数据库中导出了一些数据,为了更直观的发送给其他人查阅,便使用mongoVUE的导出为excel功能.   但是导出后出现了一个问题,里边有一列存储时间的,存储的是lon ...

  8. 在纯JaveScript中实现报表导出:从“PDF”到“JPG”

    我们在前端报表中完成了各种工作数据的输入或内容处理之后,需要做什么? 数据的导出! 这些数据的常用导出格式有:PDF.Excel.HTML和图片几大类型. 但总有一些实际应用场景,需要的不仅仅是将现有 ...

  9. Java实现Excel中的NORMSDIST函数和NORMSINV函数

    由于工作中需要将Excel中的此两种函数转换成java函数,从而计算内部评级的资本占用率和资本占用金额.经过多方查阅资料和整理,总结出如下两个转换方法 标准正态分布累计函数NORMSDIST: pub ...

随机推荐

  1. WPF 多线程处理(3)

    WPF 多线程处理(1) WPF 多线程处理(2) WPF 多线程处理(3) WPF 多线程处理(4) WPF 多线程处理(5) WPF 多线程处理(6) 首先我们需要几个属性来保存取得的数据,因为在 ...

  2. listview中getview异步加载网络图片

    前言:本以为异步加载挺简单,因为网上代码多,但真想要做好,还真不那么简单,从看代码到弄懂再到自己写,实在是有太多的东西需要学了,用了两天的时间,终于弄出来了,因为用到回调函数,所以理解起来可能难度有点 ...

  3. MAC 13信道

    房东的路由器一直连不上,手机却能连上,前天设置了13信道,后来又忘了,最后找到个连接WIFI的方法,在网络偏好设置里选择向导,诊断中可以连上wifi.

  4. 详解HTML5中的<aside>元素与<article>元素

    <aside>元素HTML<aside>元素表示一个页面的一部分, 它的内容跟这个页面的其它内容的关联性不强,或者是没有关联,单独存在.<aside>元素通常显示成 ...

  5. sublime text3 配置插件包记录

    前言: 很多插件已经开始放弃支持ST2了,所以推荐使用ST3,大量的最新插件和最新功能已经不再支持st2了. 下载地址戳这里:http://www.sublimetext.com/3 1.所有插件 易 ...

  6. POJ 1125 Stockbroker Grapevine(floyd)

    http://poj.org/problem?id=1125 题意 : 就是说想要在股票经纪人中传播谣言,先告诉一个人,然后让他传播给其他所有的经纪人,需要输出的是从谁开始传播需要的时间最短,输出这个 ...

  7. java实现大数加法、乘法(BigDecimal)

    之前写过用vector.string实现大数加法,现在用java的BigDecimal类,代码简单很多.但是在online-judge上,java的代码运行时间和内存大得多. java大数加法:求a+ ...

  8. cv论文(SPARSE REPRESENTATION相关)

    上个博文我讲了一些CNN相关的论文,比较浅显都是入门知识,这节课来总结一些稀疏表示方面的文章.至于上个博文说到的要讲的sparse coding的知识,我将会放在Deep Learning的专题里面讲 ...

  9. jdbc事务

    买书的例子 程序应该将图书数量的操作和更新account用户余额的操作作为一个事务来处理,只有这两个操作都完成的情况下,才能提交事务,否则就回滚事务. 本文转自http://blog.chinauni ...

  10. Linux基础---开关机与帮助

    1.X window与文字模式的切换 通常我们也称文字模式为 终端机接口, terminal或console!Linux预设的情况下, 会提供六个Terminal来让使用者登入,切换的方式为: [Ct ...