welcome to xlongwei.com

欢迎大家一起学习、交流、分享


QQ:9167702333 邮箱:admin@xlongwei.com

PdfUtil 生成pdf文档方案


分类 Java   关键字 分享   标签 java   web   algorithm   发布 admin  1440513190917
注意 转载须保留原文链接,译文链接,作者译者等信息。  
生成pdf文档看似容易其实不那么简单,itext可以手动生成pdf文档但是内容排版太难以控制,itext还可以填充带表单域的pdf模板文件但是需要安装Adobe Acrobat来编辑排版pdf模板,jodconverter可以调用openoffice服务来转换doc文档至pdf只是openoffice服务不易配置且占资源,xhtmlrenderer可以转换html文档至pdf只是仅支持部分xhtml标签且排版也非易事,最后还有中文显示的问题,总是困难之处一大波……

html2pdf,转换url页面或html内容至pdf,需要微调模板页面(样式难调,中文难看)
doc2pdf,转换doc文档至pdf,需要openoffice服务支持(效果最好,word文档便于编辑)
fill2form,填充pdf表单域,需要Acrobat编辑特殊的模板文档(pdf不如word编辑方便,排版难度为知)

首先引入需要的依赖,itext-2.0.8.1版本是在2.0.8版本上修改了中文不显示的bug后的版本,可以到nexus.xlongwei.com下载jar包
<dependency>
  <groupId>com.lowagie</groupId>
  <artifactId>itext</artifactId>
  <version>2.0.8.1</version>
</dependency>
<dependency>
  <groupId>com.lowagie</groupId>
  <artifactId>itext-asian</artifactId>
  <version>2.0.8.1</version>
</dependency>
<dependency>
  <groupId>org.xhtmlrenderer</groupId>
  <artifactId>core-renderer</artifactId>
  <version>2.0.8.1</version>
</dependency>
<dependency>
  <groupId>com.artofsolving</groupId>
  <artifactId>jodconverter</artifactId>
  <version>2.2.1</version>
  <exclusions>
  	<exclusion>
  		<groupId>commons-io</groupId>
  		<artifactId>commons-io</artifactId>
  	</exclusion>
  </exclusions>
</dependency>

openoffice服务配置(个人认为这个效果最好)
yum groupinstall "Office/Productivity",安装openoffice套件
yum list openoffice*,列出openoffice相关组件
yum -y install openoffice.org-langpack-zh_CN,安装中文语言包
yum -y install openoffice.org-headless.x86_64,处理错误Can't Open Display
/usr/lib64/openoffice.org3/program/soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard &,运行openoffice服务

html模板编辑事项
<body style="font-family:'Arial Unicode MS'">,中文字体
<table style="table-layout:fixed;word-break:break-strict;">,表格样式

public class PdfUtil {
	private static Logger logger = LoggerFactory.getLogger(PdfUtil.class);
	
	/** 转换html或url到pdf */
	public static boolean html2pdf(String htmlOrUri, OutputStream out) {
		try {
			ITextRenderer renderer = new ITextRenderer();
			if(htmlOrUri.startsWith("http")) renderer.setDocument(htmlOrUri);
			else renderer.setDocumentFromString(htmlOrUri);
			ITextFontResolver fontResolver = renderer.getFontResolver();
			fontResolver.addFont(GlobalConfig.getProperty("pdf.convert.arialFont"), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
			renderer.layout();
			renderer.createPDF(out);
			return true;
		} catch (DocumentException | IOException e) {
			logger.warn("fail to convert html to pdf", e);
		}
		return false;
	}
	
	/** 转换doc至pdf */
	public static boolean doc2pdf(File doc, File pdf) {
		OpenOfficeConnection connection = new SocketOpenOfficeConnection("127.0.0.1", 8100);
		try {
			connection.connect();
			DocumentConverter converter = new OpenOfficeDocumentConverter(connection);  
			logger.info("convert-pdf convert doc to pdf: "+doc.getAbsolutePath()+" => "+pdf.getAbsolutePath());
			long s = System.currentTimeMillis();
			converter.convert(doc, pdf);
			connection.disconnect();
			logger.info("convert-pdf office manager disconnect, converted in ms: "+(System.currentTimeMillis()-s));
			return true;
		} catch (ConnectException e) {
			logger.warn("fail to convert doc to pdf", e);
		}
		return false;
	}
	
	/** 填充pdf表单域 */
	public static void fill2form(File in, File out, Map<String, String> data) {
		try{
			PdfReader pdfReader = new PdfReader(new FileInputStream(in));
			PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(out));
			
			if(data!=null && data.size()>0) {
				AcroFields form = pdfStamper.getAcroFields();
				for(String key : data.keySet()) {
					String value = data.get(key);
					form.setField(key, value);
				}
			}

			pdfStamper.close();
			logger.info("success to fill2form with data: "+data);
		}catch(DocumentException | IOException e) {
			logger.warn("fail to convert html to pdf", e);
		}
	}
}

上面的代码对docx类型文档报错!还好找到了bug fix的办法:
DocumentConverter converter = new MyOpenOfficeDocumentConverter(connection);

    private static class MyOpenOfficeDocumentConverter extends OpenOfficeDocumentConverter {
        public MyOpenOfficeDocumentConverter(OpenOfficeConnection connection) {
            super(connection);
            //参考新版本3.0-beta-4添加docx支持,(这两个版本的接口变化挺大的)
            DefaultDocumentFormatRegistry formats = (DefaultDocumentFormatRegistry)getDocumentFormatRegistry();
            DocumentFormat docx = new DocumentFormat("Microsoft Word 2007 XML", DocumentFamily.TEXT, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx");
            docx.setExportFilter(DocumentFamily.TEXT, "MS Word 2007");
            formats.addDocumentFormat(docx);
        }
    }


评论列表