欢迎来到小居数码网-一家分享数码知识,生活小常识的网站,希望可以帮助到您。

当前位置:生活小常识 > 数码知识 >
优质

java(iText)工具包生成PDF(Javaitext)

数码知识

丁熙彦优秀作者

原创内容 来源:小居数码网 时间:2024-08-11 17:05:03 阅读() 收藏:45 分享:72

导读:您正在阅读的是关于【数码知识】的问题,本文由科普作家协会,生活小能手,著名生活达人等整理监督编写。本文有3672个文字,大小约为13KB,预计阅读时间10分钟。

PDF操作类库 iTextiText是一个非常著名的能够快速产生PDF文件的Java类库。支持文本,表格,图形的操作,可以方便的跟 Servlet 进行结合

Javaitext

PDF操作类库 iText

iText的更新变化很大,早期版本在PDF样式上可能会有瑕疵,所有我使用的最新的5.5.6包

1.添加Maven依赖

itext核心包 和xmlworder字体包

<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.6</version></dependency><dependency><groupId>com.itextpdf.tool</groupId><artifactId>xmlworker</artifactId><version>5.5.6</version></dependency>

2.直接生成pdf

非常简单,用文字创建段落等即可,设置好字体、间距、对齐方式等等即可,弄个Hello World 的例子。

packageiText;importcom.itextpdf.text.*;importcom.itextpdf.text.pdf.BaseFont;importcom.itextpdf.text.pdf.PdfPHeaderCell;importcom.itextpdf.text.pdf.PdfPTable;importcom.itextpdf.text.pdf.PdfWriter;importorg.junit.Test;importjava.io.FileOutputStream;/***authorwangnian*date2016/4/1*/publicclassPdfDemo_1{privatestaticvoidcreate()throwsException{//创建一个文档(默认大小A4,边距36,36,36,36)Documentdocument=newDocument();//设置文档大小document.setPageSize(PageSize.A4);//设置边距,单位都是像素,换算大约1厘米=28.33像素document.setMargins(50,50,50,50);//设置pdf生成的路径FileOutputStreamfileOutputStream=newFileOutputStream("D:/demo.pdf");//创建writer,通过writer将文档写入磁盘PdfWriterwriter=PdfWriter.getInstance(document,fileOutputStream);//demoStringtitle="打油诗";Stringcontent="大学校园真开放,宿舍竟能打麻将。东南西北皆可碰,哪管父母心血浓。";//定义字体FontFactoryImpffi=newFontFactoryImp();//注册全部默认字体目录,windows会自动找fonts文件夹的,返回值为注册到了多少字体ffi.registerDirectories();//获取字体,其实不用这么麻烦,后面有简单方法Fontfont=ffi.getFont("宋体",BaseFont.IDENTITY_H,BaseFont.EMBEDDED,12,Font.UNDEFINED,null);//打开文档,只有打开后才能往里面加东西document.open();//设置作者document.addAuthor("校园作者");//设置创建者document.addCreator("wangnian");//设置主题document.addSubject("测试");//设置标题document.addTitle("打油诗");//增加一个段落document.add(newParagraph(title,font));document.add(newParagraph(content,font));document.add(newParagraph("nr",font));//创建表格,5列的表格PdfPTabletable=newPdfPTable(4);table.setTotalWidth(PageSize.A4.getWidth()-100);table.setLockedWidth(true);//创建头PdfPHeaderCellheader=newPdfPHeaderCell();header.addElement(newParagraph(title,font));header.setColspan(4);table.addCell(header);//添加内容table.addCell(newParagraph("大学校园真开放",font));table.addCell(newParagraph("宿舍竟能打麻将",font));table.addCell(newParagraph("东南西北皆可碰",font));table.addCell(newParagraph("哪管父母心血浓",font));document.add(table);//关闭文档,才能输出document.close();writer.close();}@Testpublicvoidtest(){try{create();System.out.println("生成成功");}catch(Exceptionex){System.out.println("文件路径错误或者权限不够");}}}

3.字体

我们项目文书字体比较特殊,比如用到了宋体(99%都这个吧)、华文仿宋(安装office后自带)、仿宋_GB2312等,于是就研究了一下pdf字体,网上有很多方法使用中文字体,其实5.0版以后的iText加入字体还是很方便的。

packageiText;importjava.io.FileOutputStream;importcom.itextpdf.text.Document;importcom.itextpdf.text.Font;importcom.itextpdf.text.FontFactoryImp;importcom.itextpdf.text.Paragraph;importcom.itextpdf.text.pdf.PdfWriter;importcom.itextpdf.tool.xml.XMLWorkerFontProvider;importorg.junit.Test;/***字体**authorwangnian*date2016/4/1**/publicclassPdfDemo_2{publicstaticvoidcreate()throwsException{Documentdocument=newDocument();PdfWriterwriter=PdfWriter.getInstance(document,newFileOutputStream("D:/demo2.pdf"));Stringtitle="凉州词";Stringcontent="黄河远上白云间,一片孤城万仞山。羌笛何须怨杨柳,春风不度玉门关。";document.open();document.add(newParagraph(title,getFont("方正兰亭黑简体")));document.add(newParagraph(content,getFont("迷你简娃娃篆")));document.close();writer.close();}privatestaticFontgetFont(StringfontName){//xmlworker主要功能是html转pdf用的,非常好用,也是itext官方的//这个是xmlworker提供的获取字体方法,很方便,对中文支持很好FontFactoryImpfp=newXMLWorkerFontProvider();//注册指定的字体目录,默认构造方法中会注册全部目录,我这里注册了src/font目录fp.registerDirectory(PdfDemo_2.class.getClassLoader().getResource("weiruanyahei").getFile(),true);//最好的地方是直接支持获取中文的名字returnfp.getFont(fontName);//当然,最好的方法是自己继承XMLWorkerFontProvider,提供一些常用字体,简单方便}@Testpublicvoidtest()throwsException{create();System.out.println("生成成功");}}

xmlworker的XMLWorkerFontProvider提供了很方便的获取字体方法:

1.注册一个文件夹,里面有哪些字体都可以,比如我demo中的字体

2.使用getFont(字体名)即可获得,不过字体名从哪来的呢

4.页眉页脚

iText5中并没有之前版本HeaderFooter对象设置页眉和页脚,可以利用PdfPageEvent来完成页眉页脚的设置工作。

PdfPageEvent提供了几个pdf在创建时的事件,页眉页脚就是在每页加载完写入的。

每一页加个页码还是很简单的,但是总页码就麻烦了,iText是流模式的写入内容,只有写到最后,才能知道有多少页,那么显示总页数就麻烦了,不过麻烦不代表不可能。

其实iText仅在调用释放模板方法后才将PdfTemplate写入到OutputStream中,否则对象将一直保存在内存中,直到关闭文档。

所以我们可以在最后关闭文档前,使用PdfTemplate写入总页码。可以理解成先写个占位符,然后统一替换。

还是HelloWorld例子:

packageiText;importcom.itextpdf.text.*;importcom.itextpdf.text.pdf.*;importcom.itextpdf.tool.xml.XMLWorkerFontProvider;/***iText5中并没有之前版本HeaderFooter对象设置页眉和页脚<br>*不过,可以利用PdfPageEventHelper来完成页眉页脚的设置工作。<br>*就是在页面完成但写入内容之前触发事件,插入页眉、页脚、水印等。<br>**authorwangnian*date2016/4/1**/publicclassMyHeaderFooterextendsPdfPageEventHelper{Fontfont=newXMLWorkerFontProvider().getFont("宋体",12,BaseColor.RED);//总页数PdfTemplatetotalPage;//打开文档时,创建一个总页数的模版publicvoidonOpenDocument(PdfWriterwriter,Documentdocument){PdfContentBytecb=writer.getDirectContent();totalPage=cb.createTemplate(30,16);}//一页加载完成触发,写入页眉和页脚publicvoidonEndPage(PdfWriterwriter,Documentdocument){PdfPTabletable=newPdfPTable(3);try{table.setTotalWidth(PageSize.A4.getWidth()-100);table.setWidths(newint[]{24,24,3});table.setLockedWidth(true);table.getDefaultCell().setFixedHeight(-10);table.getDefaultCell().setBorder(Rectangle.BOTTOM);table.addCell(newParagraph("我是文字",font));//可以直接使用addCell(str),不过不能指定字体,中文无法显示table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);table.addCell(newParagraph("第"+writer.getPageNumber()+"页/",font));//总页数PdfPCellcell=newPdfPCell(Image.getInstance(totalPage));cell.setBorder(Rectangle.BOTTOM);table.addCell(cell);//将页眉写到document中,位置可以指定,指定到下面就是页脚table.writeSelectedRows(0,-1,50,PageSize.A4.getHeight()-20,writer.getDirectContent());}catch(Exceptionde){thrownewExceptionConverter(de);}}//全部完成后,将总页数的pdf模版写到指定位置publicvoidonCloseDocument(PdfWriterwriter,Documentdocument){Stringtext="总"+(writer.getPageNumber()-1)+"页";ColumnText.showTextAligned(totalPage,Element.ALIGN_LEFT,newParagraph(text,font),2,2,0);}}
packageiText;importjava.io.FileOutputStream;importcom.itextpdf.text.BaseColor;importcom.itextpdf.text.Document;importcom.itextpdf.text.Element;importcom.itextpdf.text.ExceptionConverter;importcom.itextpdf.text.Font;importcom.itextpdf.text.Image;importcom.itextpdf.text.PageSize;importcom.itextpdf.text.Paragraph;importcom.itextpdf.text.Rectangle;importcom.itextpdf.text.pdf.ColumnText;importcom.itextpdf.text.pdf.PdfContentByte;importcom.itextpdf.text.pdf.PdfPCell;importcom.itextpdf.text.pdf.PdfPTable;importcom.itextpdf.text.pdf.PdfPageEventHelper;importcom.itextpdf.text.pdf.PdfTemplate;importcom.itextpdf.text.pdf.PdfWriter;importcom.itextpdf.tool.xml.XMLWorkerFontProvider;importorg.junit.Test;/***页眉、页脚*authorwangnian*date2016/4/1*/publicclassPdfDemo_3{publicstaticvoidcreate()throwsException{Documentdocument=newDocument(PageSize.A4,50,50,50,50);PdfWriterwriter=PdfWriter.getInstance(document,newFileOutputStream("d:/demo3.pdf"));//增加页眉页脚writer.setPageEvent(newMyHeaderFooter());Stringtitle="凉州词";Stringcontent="黄河远上白云间,一片孤城万仞山。羌笛何须怨杨柳,春风不度玉门关。";document.open();Fontfont=newXMLWorkerFontProvider().getFont("宋体");for(inti=0;i<100;i++){document.add(newParagraph(title,font));document.add(newParagraph(content,font));document.add(newParagraph("n"));}document.close();writer.close();}@Testpublicvoidtest()throwsException{create();System.out.println("生成成功");}}

5.html转pdf

结果还不错,虽然可以满足我们的要求,但是比较复杂,动态创建一个个的表格和内容过于繁琐,方法太粗暴了,用户 的文档内容或格式变化,就要修改程序了。

先创建html,然后转换成pdf,demo如下:

packageiText;importjava.io.ByteArrayInputStream;importjava.io.FileOutputStream;importjava.io.InputStream;importjava.io.OutputStream;importcom.itextpdf.text.Document;importcom.itextpdf.text.pdf.PdfWriter;importcom.itextpdf.tool.xml.XMLWorkerHelper;importorg.junit.Test;/***html转pdf*authorwangnian*date2016/4/1**/publicclassPdfDemo_4{publicstaticvoidcreate()throwsException{//html中字体非常郁闷//1.html中不指定字体,则默认使用英文字体,中文会不显示。//2.html中指定的字体必须是英文名称,如宋体:font-family:SimSun;//3.html中不能指定自定义字体,必须指定itext支持的字体,还好itext支持字体比较多,常见操作系统带的都支持//4.暂没有找到如何html中支持自定义字体方法,网上都是修改源码实现默认字体中文,也很重要StringBuilderhtml=newStringBuilder();html.append("<html>");html.append("<bodystyle='font-size:20px;font-family:SimSun;'>");html.append("<tablewidth='19cm'border='1'cellpadding='0'cellspacing='0'>");html.append("<tr>");html.append("<tdcolspan='2'>凉州词</td>");html.append("</tr>");html.append("<tr>");html.append("<td>黄河远上白云间,一片孤城万仞山。</td>");html.append("<td>羌笛何须怨杨柳,春风不度玉门关。</td>");html.append("</tr>");html.append("</table>");html.append("</body>");html.append("</html>");InputStreamis=newByteArrayInputStream(html.toString().getBytes());OutputStreamos=newFileOutputStream("D:/demo4.pdf");Documentdocument=newDocument();PdfWriterwriter=PdfWriter.getInstance(document,os);document.open();//将html转pdfXMLWorkerHelper.getInstance().parseXHtml(writer,document,is);document.close();}@Testpublicvoidtest()throwsException{create();System.out.println("生成成功");}}

此处使用了XmlWorker,XmlWorker也是iText官方的,目前和iText版本一起更新,可以讲XHTML转换成pdf,支持大部分样式和标签,是大部分哦,不是全部。

目前我们就用的这个方式,写好html文档,使用时动态替换html中的标记位,然后生成pdf。

使用XHTML转pdf要注意的地方:

1. html中不指定字体,则默认使用英文字体,中文会不显示;

2. html中指定的字体必须是英文名称;如宋体:font-family:SimSun;正确 font-family:宋体;则错误,竟然unicode也不行。

3. html中不能指定自定义字体(比如上文中的方正兰亭黑),但是itext一般操作系统的字体都支持,如果ubuntu上没有微软雅 黑,可以从windows下拷贝雅黑字体Yahei.ttf 放进来ubuntu上/usr/share/fonts/路径。

4. pdf中添加图片也非常简单,例如:<img src='d:/1.jpg'/>,就可以了。

5. XHTML不是HTML,所以任何标签都要完整结束,比如<br>错误,必须<br/>才行。

写一个html模版很简单,需要对html和css熟练,调生成的样式部分比较麻烦(比如文字多了会切掉,不切会影响整体样式,表格线有粗有细,xmlworker不支持全部css等),一般A4纸都是厘米单位的,html中最好也使用厘米,处理简单点。

上面就是小居数码小编今天给大家介绍的关于(Javaitext)的全部内容,希望可以帮助到你,想了解更多关于数码知识的问题,欢迎关注我们,并收藏,转发,分享。

94%的朋友还想知道的:

(455)个朋友认为回复得到帮助。

部分文章信息来源于以及网友投稿,转载请说明出处。

本文标题:java(iText)工具包生成PDF(Javaitext):http://sjzlt.cn/shuma/154710.html

猜你喜欢