利用 POI 修改插入图表

这篇博客主要记录了如何使用Apache POI库在Java中自定义插入Word图表,尤其是折线图。作者提到现有的工具如easypoi和poi-tl在处理带有图表的模板时存在限制,因此选择通过自定义插件来实现。博客详细介绍了定位模板图表、数据结构、绘制线条和数据的过程,以及遇到的Office打不开文件的问题。尽管这种方式提供了一种插入图表的思路,但存在图表标题无法更改、样式丢失等局限性。
摘要由CSDN通过智能技术生成

案例

利用 POI 进行 word 模板替换已经有很成熟的方案了,开源的工具就有 easypoi,以及最近发现的工具 poi-tl,都是模板替换,用法大同小异。

团队内部现在总结发现,用 easypoi 进行 excel 导入导出,模板替换比较方便,但是在 word 方面目前来看 poi-tl,优势更大,因为其既拥有 easypoi 的优势,又弥补了一些不足,比如图片的环绕,可以通过其插件解决,而且也提供自定义插件支持,可以更灵活。

但是最近有个需求,在word模板中有图表的存在,现存的两个工具都无法满足,只能支持图片插入。因此决定通过自定义其引用插件,来满足需求。

在自定义插件时,发现使用poi-tl还是很方便和简单的,麻烦的是自己去操作图表,由于自己太菜以及对 poi 的认识还严重不足,走了很多路,所以这里记录下。

引用

学习 poi 完全是瞎撞,也不知道各位大佬是如何学习的,为了解决图表问题,能用的资料太少了,这里就贴一些:

  1. java使用poi在word中生成柱状图、折线图、饼图、柱状图+折线图组合图、动态表格、文本替换、图片替换、更新内置Excel数据、更新插入的文本框内容、合并表格单元格
  2. 官方 javaDoc
  3. 官方 示例源码

这里感谢下 我们都有 博主提供的示例源码。

使用记录

目前只是研究了下折线图,其他的还没来的及。

获取图表,定位模板图表

我们都有 博主的思路是通过,图表的编辑数据第一行第一列的交叉格子(org.apache.poi.xssf.usermodel.XSSFCell),在这里输入标识符来定位,其方法提供是getZeroData

示例

我将方法稍微调整了下,思路是一样的,直接贴代码:

// 获取所有图表
List<XWPFChart> charts = document.getCharts();
for (XWPFChart chart : charts) {
    XSSFWorkbook workbook = chart.getWorkbook();
    XSSFSheet sheet1 = workbook.getSheetAt(0);
    XSSFCell cell = sheet1.getRow(0).getCell(0);
    String firstCellValue = cell.getStringCellValue();
    // optionalText() 为标识符获取方法
    if (StrUtil.equals(firstCellValue, optionalText())) {
        findCharts.add(chart);
    }
}

定位代码后,就是操作了

渲染数据
数据结构

渲染数据之前是填入数据,我们都有 博主提供的数据结构,个人觉得太凌乱了,所以我总结了一下,定义如下

@Data
public class LineChartRenderData {
    /**
     * 图名
     */
    private String title;
    /**
     * 折线
     */
    private List<LineData> lines;
    /**
     * 横坐标
     */
 
项目想实现excel图表POI不支持所以想到了这个方法。放上来抛砖引玉,感兴趣的欢迎大家交流 注:-------------------------------------------------------------------------- 其实现原理和利用JavaScript实现客户端绘图完全一样。后台代码将输入 写入特定区域,前端脚本在页面载入时执行脚本绘图。大家都是做B/S开发 的,这方面的只是不需要我多说了吧。 如果我们让一个HTML页面在载入时显示一个提示框用后台编程是不现实的 所以我们就动态生成一段JS: window.onload=function(){ ...... } 用Java输出图表的场景和这个一样,POI、JXL对操作Excel图表无能为力 但Excel支持脚本的,也有工作表载入事件,所以也可以用同样的原理实现 只不过这次客户端不再是浏览器而是Excel应用程序。 这样交代的应该比较明白了吧,请不要再留言抱怨没有Java代码了,因为 这根本跟java代码没多大关系,后台的代码所做的工作仅仅是写入必要的 数据,数据的解析和绘图操作是在VBA完成的 ---2009-12-18 今天查找资料翻出来了这段代码,发现里边的类确实是空的,我说怎么总挨骂 呢,当时肯定打包的时候晕透了把另一个本该删除的类打包进去了。我无法 替换文件只能把java代码贴上来了,请自己修改模板文件的路径。 package com.test.poi; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.POIFSFileSystem; public class PoiChart { public static void main(String[] args){ try{ POIFSFileSystem fs=new POIFSFileSystem(new FileInputStream("E:/王建波_bak/我的练习/Module.xls")); HSSFWorkbook wb=new HSSFWorkbook(fs); HSSFSheet sheet=wb.getSheetAt(0); HSSFRow row; //写入表头 String[] aTblHeaders=new String[]{ "姓名","语文","数学","英语" }; row=sheet.createRow(0); for(int i=0,len=aTblHeaders.length;i<len;i++){ row.createCell((short)i).setCellValue(aTblHeaders[i]); } //向模板写入数据 String[] aNames=new String[]{ "张飞","刘备","关羽","曹操","孙权","吕布" }; for(int i=0,nRowLen=aNames.length;i<nRowLen;i++){ row=sheet.createRow(i+1); row.createCell((short)0).setCellValue(aNames[i]); for(int j=1,nColLen=aTblHeaders.length;j<nColLen;j++){ row.createCell((short)j).setCellValue(Math.floor(Math.random()*100)); } } //输出文件 FileOutputStream fout=new FileOutputStream("d:/chart.xls"); wb.write(fout); fout.close(); }catch(Exception e){ e.printStackTrace(); } } }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值