从浏览器导出word 文档,包含图片和表格

本文参考文章:

1、 java导出word的5种方式   https://blog.csdn.net/zi_wu_xian/article/details/80320520 

2、jfreechart形成各种图    https://blog.csdn.net/chehec2010/article/details/81026789

3、jFreeChart 详细属性总结  https://blog.csdn.net/it_lihongmin/article/details/50469212

4、Java使用iText生成word文件的完美解决方案   https://blog.csdn.net/matinbell/article/details/73088948

5、使用iText在word文档中插入复杂的Table表格   https://blog.51cto.com/116833/1688695

6、ITEXT table的单元格边框设置   https://blog.csdn.net/cfup_less/article/details/82686426

需求描述

需要把从数据库里查询出来的数据,从浏览器中导出到一个word文档,文档中包含折线图,饼状图,还有表格,文字等。

一、大致思路

      刚开始做的时候,觉得需求最大的问题在于能不能找到一种第三方的插件来实现在word 中画出折线图和饼状图,  后来通过从网上查找资料(见参考文章1),最后经过比较和权衡,决定使用第三方插件来先生成需要的折线图和饼状图,然后再向word中插入图片这种方式来实现。

二、用到的插件

使用 itext 和 itext-rtf 来操作word 文档,使用 jfreechart 来生成各种图表,下面列出了需要用到的jar maven依赖,其中itext 这两个jar包的版本要一直

		<dependency>
		    <groupId>org.jfree</groupId>
		    <artifactId>jfreechart</artifactId>
		    <version>1.0.19</version>
		</dependency>
        <dependency>
			<groupId>com.lowagie</groupId>
			<artifactId>itext</artifactId>
			<version>2.1.7</version>
			<type>jar</type>
		</dependency>
		
		<dependency>
		    <groupId>com.lowagie</groupId>
		    <artifactId>itext-rtf</artifactId>
		    <version>2.1.7</version>
		</dependency>

   三、代码展示

用到的代码基本上都是从网上找的,然后在根据自己的具体需求再去改造。(原谅我没有时间去具体细看),写这篇文章也是为了总结一下用到的知识,然后把东西汇总一下,方便以后再用。

1、生成图片

这部分的代码主体主要参考了下面两篇文章,然后在这个的基础上进行了改造。

https://blog.csdn.net/chehec2010/article/details/81026789

https://blog.csdn.net/it_lihongmin/article/details/50469212

    说一下改造过程中遇到的几个问题。

    首先是 折线图刻度取值问题,因为要生成好几个折线图,而且几个折线图Y轴的取值范围差距也很大,不能写成一个定值。于是我就想了一种思路,所有值求和然后求平均数,再取一半的值。但是这样取到的值还有小数点,个位十位上都会有值,比如5.83,1453.5 等等这种,刻度线上的值还是整百整十这种比较好。然后我就又通过代码再取了一次值。思路是通过判断平均数的范围,然后给定一个基数,通过先除后乘这种操作来获得整值。下面是代码

    		int num = ((int)sum/2)/list.size();
    		int radix = 0;
    		if (num < 10) {
    			radix = 1;
    		} else if (num >= 10 && num < 100) {
    			radix = 10;
    		} else if (num >= 100 && num < 1000) {
    			radix = 100;
    		} else if (num >= 1000 && num < 10000) {
    			radix = 1000;
    		} else if (num >= 10000 && num < 100000) {
    			radix = 10000;
    		} else if (num >= 100000 && num < 1000000) {
    			radix = 100000;
    		} else if (num >= 1000000 && num < 10000000) {
    			radix = 1000000;
    		} else {
    			radix = 5000000;
    		}
    		 tick= num / radix * radix;

 

    再就是图例的乱码问题,找了好久,通过给图例上的字重新设置字体就能解决。

折线图:

  // 横坐标

        Font labelFont = new Font("仿宋", Font.TRUETYPE_FONT, 18);
        CategoryAxis domainAxis = categoryplot.getDomainAxis();
        domainAxis.setLabelFont(labelFont);// 轴标题

       纵坐标

        NumberAxis numberaxis = (NumberAxis) categoryplot.getRangeAxis();
        numberaxis.setLabelFont(labelFont);

饼状图:

        StandardChartTheme standardChartTheme=new StandardChartTheme("CN"); 
        standardChartTheme.setRegularFont(new Font("宋书",Font.PLAIN,8));  
        ChartFactory.setChartTheme(standardChartTheme);

2、生成word文档

生成word文档时,主要参考了下面这篇文章

 https://blog.csdn.net/matinbell/article/details/73088948

说一下碰到的几个问题

①生成文档的页边距控制不好,几乎把整个页面都占满了,后来通过查询资料,才知道 一些。

生成文档时 Document document = new Document(PageSize.A4,90,90,72,72); 可以设置左右的边界,90 和 72 基本都是通用的A4 纸的边距大小。

② word文档的字体怎么设置,大部分的网上教程都是直接让从本地的c盘的Windows字库中直接拿rtf 文件,但是我怎么试都不行,最后找到一种方式

RtfFont font =new RtfFont("仿 宋", 12, Font.NORMAL, Color.BLACK);

注意字体仿宋之间 有一个空格。

③因为是用浏览器导出的,所以要将字节流输出到 response 中返回给浏览器,使用 BufferedOutputStream 来包装了一下response的输出流,然后使用 RtfWriter2来写word 文档

		OutputStream os = null;
		response.reset();
		response.setHeader("Content-Disposition", "attachment;filename="
				+ new String((cityString+"检查结果"+simdf.format(new Date()) + ".doc").getBytes("gbk"),"iso8859-1"));
		//response.setHeader("Content-Length", "" + file.length());
		os = new BufferedOutputStream(response.getOutputStream());
		response.setContentType("application/xml");

		String path = "E:\\test\\";// word 文档中需要的图片 保存的路径
 		if(System.getProperty("os.name").toLowerCase().startsWith("linux")){
 			path ="/home/Tomcat/temp/";
	 		File file = new File(path);
 			if (!file.exists()) {
				file.mkdir();
			}
 		}
		
		DateFormat sFormat = new SimpleDateFormat("yyyy年MM月");
		DateFormat sFormat1 = new SimpleDateFormat("yyyy-MM");
		Document document = new Document(PageSize.A4,90,90,72,72);
		
		//使用 rtf 来写word 文档
		RtfWriter2.getInstance(document, os); 
		document.open();

④ 关于table  和 table 单元格的边框设置,可以参考下面两篇文章

https://blog.51cto.com/116833/1688695

https://blog.csdn.net/cfup_less/article/details/82686426

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值