Java通过IText导出word和pdf

29 篇文章 5 订阅

最近做的项目中需要用到导出word和pdf的功能(还有图表),在网上找了很多资料,最后敲定用了IText组件,下面是我项目中的一个Demo,记录了一下,希望对需要的人有帮助。


相关jar包下载地址:http://download.csdn.net/detail/zwx19921215/8368135


IText操作类

package com.tgb.util;

import java.awt.Color;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.rtf.RtfWriter2;
import com.tgb.entity.News;

/**
 * IText操作类
 * @author shyh
 *
 */
public class ItextManager {

	private Font font;
	private BaseFont bfChinese;

	public ItextManager() throws Exception {
		// 设置中文字体
		bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
		font = new Font(bfChinese);
		font.setSize(15);
		font.setStyle(FontFactory.HELVETICA);
//		font.setStyle(Font.BOLD);//加粗
		font.setColor(new Color(0,0,0));
		
	}

	public static ItextManager getInstance() throws Exception {
		return new ItextManager();
	}

	public void createRtfContext(List<News> newsList, List<String> imgList, OutputStream out,String type) {
		Document doc = new Document(PageSize.A4, 20, 20, 20, 20);
		try {
			if("word".equals(type)){
				RtfWriter2.getInstance(doc, out);
			}else if("pdf".equals(type)){
				PdfWriter.getInstance(doc, out);
			}
			doc.open();
			News news = null;
			Paragraph title1 = null;
			for (int i = 0; i < newsList.size(); i++) {
				news = newsList.get(i);
				// 标题
				Paragraph title = new Paragraph(news.getTitle(), font);
				title.setAlignment(Element.ALIGN_LEFT);
				doc.add(title);

				// 换行
				title1 = new Paragraph("\n");
				doc.add(title1);

				// 正文
				Paragraph content = new Paragraph(news.getContent(), font);
				content.setAlignment(Element.ALIGN_LEFT);
				doc.add(content);

				// 换行
				title1 = new Paragraph("\n");
				doc.add(title1);

				// 站点
				Paragraph site = new Paragraph(news.getSite(), font);
				content.setAlignment(Element.ALIGN_LEFT);
				doc.add(site);

				// 换行
				title1 = new Paragraph("\n");
				doc.add(title1);

				// 发布时间
				Paragraph publishTime = new Paragraph(news.getPublishTime(), font);
				content.setAlignment(Element.ALIGN_LEFT);
				doc.add(publishTime);

				// 换行
				title1 = new Paragraph("\n");
				doc.add(title1);

			}

			Image img = null;
			for (int j = 0; j < imgList.size(); j++) {
				// 图片
				img = Image.getInstance(imgList.get(j));
				float heigth = img.getHeight();
				float width = img.getWidth();
				int percent = getPercent2(heigth, width);
				img.setAlignment(Image.MIDDLE);
				img.scalePercent(percent + 3);// 表示是原来图像的比例;
				doc.add(img);
			}

			doc.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 第一种解决方案 在不改变图片形状的同时,判断,如果h>w,则按h压缩,否则在w>h或w=h的情况下,按宽度压缩
	 * 
	 * @param h
	 * @param w
	 * @return
	 */

	public static int getPercent(float h, float w) {
		int p = 0;
		float p2 = 0.0f;
		if (h > w) {
			p2 = 297 / h * 100;
		} else {
			p2 = 210 / w * 100;
		}
		p = Math.round(p2);
		return p;
	}

	/**
	 * 第二种解决方案,统一按照宽度压缩 这样来的效果是,所有图片的宽度是相等的,自我认为给客户的效果是最好的
	 * 
	 * @param args
	 */
	public static int getPercent2(float h, float w) {
		int p = 0;
		float p2 = 0.0f;
		p2 = 530 / w * 100;
		p = Math.round(p2);
		return p;
	}
}

控制层(springmvc)

	@RequestMapping(value="/exportword")
	public String exportWord(HttpServletRequest request,HttpServletResponse response) throws Exception{
		String type = request.getParameter("type");
		response.setContentType("application/octet-stream; charset=UTF-8");  
		if("word".equals(type)){
			response.setHeader("content-disposition", "attachment;filename=" + new SimpleDateFormat("yyyyMMddHH:mm:ss").format(new Date()) + ".doc");
		}else if("pdf".equals(type)){
			response.setHeader("content-disposition", "attachment;filename=" + new SimpleDateFormat("yyyyMMddHH:mm:ss").format(new Date()) + ".pdf");
		}
		
		String svgCode = request.getParameter("svg");//highcharts图表svgCode
		String svg [] = svgCode.split("_");
		String path[] = new String[svg.length];
		OutputStream out = response.getOutputStream();
		ItextManager tm = ItextManager.getInstance();
		List<News> newsList = userService.getData();
		List<String> imageList = new ArrayList<String>();
		
		if(svg!=null){
			for(int k=0;k<svg.length;k++){
				String picName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+".png";
				path[k] = request.getSession().getServletContext().getRealPath("/upload/"+picName);
				imageList.add(path[k]);
				SvgPngConverter.convertToPng(svg[k], path[k]);
			}
		}
		
		tm.createRtfContext(newsList,imageList,out,type);
		
		out.flush();
		out.close();
		return null;
	}



业务层

@Override
	public List<News> getData() {
		List<News> newsList = new ArrayList<News>();
		News news1 = new News();
		news1.setTitle("标题:国泰君安*公司研究*广发证券:定增完成,如虎添翼*000776*投资银行业与经纪业行业*梁静");
		news1.setContent("正文:报告类型=公司事件点评公司简称=广发证券公司代码=000776报告日期=Thu Aug 25 09:05:29 CST 2011研究员 =梁静报告标题=定增完成,如虎添翼【报告摘要】8月25日,广发证券成功向揭阳市信宏资产、汇添富基金、上海海博鑫惠、兴业基金等10家机构定向增发4.526亿股、募集资金121.8亿元,募集资金净额120亿元。");
		news1.setSite("站点:新浪网");
		news1.setPublishTime("发布时间:2014-05-12");
		
		News news2 = new News();
		news2.setTitle("标题:[申万销售夏敬慧] 基金仓位周报----开基仓位下降1.51%");
		news2.setContent("正文:理财产品部分析师: 杨鹏(18930809297) 开基仓位有所下降:本周,开放式基金平均仓位继续下降。");
		news2.setSite("站点:腾讯网");
		news2.setPublishTime("发布时间:2014-05-25");
		
		newsList.add(news1);
		newsList.add(news2);
		
		return newsList;
	}

显示层

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>导出word</title>
<script type="text/javascript" src="js/jquery/jquery-1.7.1.js"></script>
<script src="js/highcharts/4.0.1/js/highcharts.js"></script>
<script src="js/highcharts/4.0.1/js/modules/exporting.js"></script>
<script type="text/javascript">
	$(function() {
		Highcharts.wrap(Highcharts.Chart.prototype, 'getSVG', function (proceed) {
		    return proceed.call(this)
		        .replace(
		            /(fill|stroke)="rgba\(([ 0-9]+,[ 0-9]+,[ 0-9]+),([ 0-9\.]+)\)"/g, 
		            '$1="rgb($2)" $1-opacity="$3"'
		        );
		});
		
		$('#container').highcharts({
			title : {
				text : 'Monthly Average Temperature',
				x : -20
			//center
			},
			subtitle : {
				text : 'Source: WorldClimate.com',
				x : -20
			},
			xAxis : {
				categories : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
			},
			yAxis : {
				title : {
					text : 'Temperature (°C)'
				},
				plotLines : [ {
					value : 0,
					width : 1,
					color : '#808080'
				} ]
			},
			tooltip : {
				valueSuffix : '°C'
			},
			legend : {
				layout : 'vertical',
				align : 'right',
				verticalAlign : 'middle',
				borderWidth : 0
			},
			series : [ {
				name : 'Tokyo',
				data : [ 7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6 ]
			}, {
				name : 'New York',
				data : [ -0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5 ]
			}, {
				name : 'Berlin',
				data : [ -0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0 ]
			}, {
				name : 'London',
				data : [ 3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8 ]
			} ]
		});

		$('#container_pie').highcharts({
			chart : {
				plotBackgroundColor : null,
				plotBorderWidth : null,
				plotShadow : false
			},
			title : {
				text : 'Browser market shares at a specific website, 2010'
			},
			tooltip : {
				pointFormat : '{series.name}: <b>{point.percentage:.1f}%</b>'
			},
			plotOptions : {
				pie : {
					allowPointSelect : true,
					cursor : 'pointer',
					dataLabels : {
						enabled : true,
						color : '#000000',
						connectorColor : '#000000',
						format : '<b>{point.name}</b>: {point.percentage:.1f} %'
					}
				}
			},
			series : [ {
				type : 'pie',
				name : 'Browser share',
				data : [ [ 'Firefox', 45.0 ], [ 'IE', 26.8 ], {
					name : 'Chrome',
					y : 12.8,
					sliced : true,
					selected : true
				}, [ 'Safari', 8.5 ], [ 'Opera', 6.2 ], [ 'Others', 0.7 ] ]
			} ]
		});

		$("#btn_word").on("click", function() {
			var chart_line = $("#container").highcharts();
			var chart_pie = $("#container_pie").highcharts();
			var svg_line = chart_line.getSVG();
			var svg_pie = chart_pie.getSVG();
			var svg = svg_line+"_"+svg_pie;
			$("#svg").val(svg);
			$("#form1").prop("action", "exportword.do?type=word").submit();
		});

		$("#btn_pdf").on("click", function() {
			var chart_line = $("#container").highcharts();
			var chart_pie = $("#container_pie").highcharts();
			var svg_line = chart_line.getSVG();
			var svg_pie = chart_pie.getSVG();
			var svg = svg_line + "_" + svg_pie;
			$("#svg").val(svg);
			$("#form1").prop("action", "exportword.do?type=pdf").submit();
		});
	});
</script>
</head>
<body>
	<form id="form1" action="exportword.do" method="post">
		<div>
			<input type="hidden" name="svg" id="svg" /> 
			<input id="btn_word" type="button" value="导出word" /> 
			<input id="btn_pdf" type="button" value="导出pdf" />
		</div>
	</form>

	<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
	<div id="container_pie" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
</html>


效果:




导出word:


导出Pdf:



  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值