使用JAVA生成PDF的时候,还是有些注意事项需要处理的。

第一、中文问题,默认的itext是不支持中文的,想要支持,需要做些处理。

  1、直接引用操作系统的中文字体库支持,由于此方案限制性强,又绑定了操作系统,所以此处不做实现,有兴趣可在网上搜索看看。

  2、引用itext-asian.jar包的字体支持,代码稍后上。

    itext pdf引入中文常见异常:

    com.itextpdf.text.DocumentException: Font 'STSongStd-Light' with 'UniGB-UCS2-H' is not recognized.

    解决方案:a、引入操作系统字体;2、将字体维护进jar包中,如果没有,直接找到字体放入对应jar包中,如果是路径错误,则更改包路径;3、通过itext-asian.jar来加载中文包。

第二、表格中的设置,特别是上中下,左中右,不同的对象有不同的枚举实现,刚入手很容易混淆。其外是前景色,背景色,表格颜色等等。

第三、输出图片,很容易报错。

    itext pdf常见输出图片异常:

    An error exists on this page. Acrobat may not display the page correctly. Please contact the person who created the PDF document to correct the problem.

    原因:PdfContentByte在addImage的时候需要在beginText()和endText()范围以外调用,否则生成的PDF就会报上述错误。

示例:

 package com.itext.test;

 import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random; import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BarcodeQRCode;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter; public class D { private static String path = "docs/"; // 生成PDF后的存放路径
private static final String logoPath = "logo.png"; public static void main(String[] args) {
// T t = new T();
initPDF(initData());
} /**
* 初始化PDF
*
* @param apis
*/
public static void initPDF(List<Api> apis) {
File folder = new File(path);
if (!folder.exists())
folder.mkdirs(); // 创建目录
Document doc = null;
try {
// 中文字体,要有itext-asian.jar支持(默认的itext.jar是不支持中文的)
BaseFont bfchinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Rectangle pageSize = new Rectangle(PageSize.A4); // 页面大小设置为A4
doc = new Document(pageSize, 20, 20, 40, 40); // 创建doc对象并设置边距
PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(folder.getAbsolutePath() + File.separator + "API文档.pdf"));
writer.setPageEvent(new SdkPdfPageEvent());
doc.open();
doc.addAuthor("Ares-xby");
doc.addSubject("SDK附属API文档");
doc.addTitle("API文档");
BaseColor borderColor = new BaseColor(90, 140, 200);
BaseColor bgColor = new BaseColor(80, 130, 180);
for (Api api : apis) {
PdfPTable table = new PdfPTable({0.25f, 0.25f, 0.25f, 0.25f});
// table.setWidthPercentage(100); // 设置table宽度为100%
// table.setHorizontalAlignment(PdfPTable.ALIGN_CENTER); // 设置table居中显示
for (int i = 0; i < api.getParams().size(); i++) {
if (i == 0) {
// row 1
table.addCell(createCell("API", bfchinese, borderColor, bgColor));
table.addCell(createCell(api.getApiName(), 12, bfchinese, 3, null, borderColor, bgColor));
// row 2
table.addCell(createCell("描述", bfchinese, borderColor));
table.addCell(createCell(api.getApiDesc(), 12, bfchinese, 3, null, borderColor));
} else {
table.addCell(createCell(api.getParams().get(i).getParamName(), 10, bfchinese, null, Paragraph.ALIGN_RIGHT, borderColor));
table.addCell(createCell(api.getParams().get(i).getParamName(), 10, bfchinese, null, null, borderColor));
table.addCell(createCell(api.getParams().get(i).getParamType(), 10, bfchinese, null, null, borderColor));
table.addCell(createCell(api.getParams().get(i).getParamDesc(), 10, bfchinese, null, null, borderColor));
}
}
doc.add(table);
}
// 二维码
BarcodeQRCode qrcode = new BarcodeQRCode("http://www.baidu.com", 1, 1, null);
Image qrcodeImage = qrcode.getImage();
qrcodeImage.setAbsolutePosition(10, 600);
qrcodeImage.scalePercent(200);
doc.add(qrcodeImage);
doc.close();
System.out.println("init pdf over.");
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (doc != null)
doc.close();
} } public static List<Api> initData() {
List<Api> list = new ArrayList<Api>();
for (int i = 0; i < 100; i++) {
Api api = new Api();
api.setApiName("api-" + i);
api.setApiDesc("描述-" + i);
int paramSize = new Random().nextInt(20);
List<Params> paramList = new ArrayList<Params>();
for (int j = 0; j < paramSize; j++) {
Params param = new Params();
param.setParamName("param-" + i + "-" + j);
param.setParamType("paramType-" + i + "-" + j);
param.setParamDesc("描述-" + i + "-" + j);
paramList.add(param);
}
api.setParams(paramList);
list.add(api);
}
System.out.println("init data over. size=" + list.size());
return list;
}
// 用於生成cell
private static PdfPCell createCell(String text, BaseFont font, BaseColor borderColor) {
return createCell(text, 12, font, null, null, borderColor, null);
}
// 用於生成cell
private static PdfPCell createCell(String text, BaseFont font, BaseColor borderColor, BaseColor bgColor) {
return createCell(text, 12, font, null, null, borderColor, bgColor);
}
// 用於生成cell
private static PdfPCell createCell(String text, int fontsize, BaseFont font, Integer colspan, Integer align, BaseColor borderColor) {
return createCell(text, fontsize, font, colspan, align, borderColor, null);
} /**
* 用於生成cell
* @param text Cell文字内容
* @param fontsize 字体大小
* @param font 字体
* @param colspan 合并列数量
* @param align 显示位置(左中右,Paragraph对象)
* @param borderColor Cell边框颜色
* @param bgColor Cell背景色
* @return
*/
private static PdfPCell createCell(String text, int fontsize, BaseFont font, Integer colspan, Integer align, BaseColor borderColor, BaseColor bgColor) {
Paragraph pagragraph = new Paragraph(text, new Font(font, fontsize));
PdfPCell cell = new PdfPCell(pagragraph);
cell.setFixedHeight(20);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 上中下,Element对象
if (align != null)
cell.setHorizontalAlignment(align);
if (colspan != null && colspan > 1)
cell.setColspan(colspan);
if (borderColor != null)
cell.setBorderColor(borderColor);
if (bgColor != null)
cell.setBackgroundColor(bgColor);
return cell;
} /**
* SDK中PDF相关的PageEvent
*/
static class SdkPdfPageEvent extends PdfPageEventHelper { @Override
public void onStartPage(PdfWriter writer, Document document) {
// 水印(water mark)
PdfContentByte pcb = writer.getDirectContent();
pcb.saveState();
BaseFont bf;
try {
bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
pcb.setFontAndSize(bf, 36);
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 透明度设置
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.2f);
pcb.setGState(gs); pcb.beginText();
pcb.setTextMatrix(60, 90);
pcb.showTextAligned(Element.ALIGN_LEFT, "XX公司有限公司", 200, 300, 45); pcb.endText();
pcb.restoreState();
} @Override
public void onEndPage(PdfWriter writer, Document document) {
// 页眉、页脚
PdfContentByte pcb = writer.getDirectContent();
try {
pcb.setFontAndSize(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED), 10);
} catch (Exception e) {
e.printStackTrace();
} // 支持中文字体
pcb.saveState();
try {
// pcb.addImage()方法要在pcb.beginText();pcb.endText();之外调用,
// 否则生成的PDF打开时会报错: An error exists on this page. Acrobat may not display the page correctly. Please contact the person who created the PDF document to correct the problem.
byte[] logoBytes = new byte[1000 * 1024]; // 此处数组大小要比logo图片大小要大, 否则图片会损坏;能够直接知道图片大小最好不过.
InputStream logoIs = getClass().getResourceAsStream(logoPath);
if(logoIs != null){
int logoSize = logoIs.read(logoBytes); // 尝试了一下,此处图片复制不完全,需要专门写个方法,将InputStream转换成Byte数组,详情参考org.apache.io.IOUtils.java的toByteArray(InputStream in)方法
if(logoSize > 0){
byte[] logo = new byte[logoSize];
System.arraycopy(logoBytes, 0, logo, 0, logoSize);
Image image = Image.getInstance(logo);// 如果直接使用logoBytes,并且图片是jar包中的话,会报图片损坏异常;本地图片可直接getInstance时候使用路径。
image.setAbsolutePosition(document.left(), document.top(-5)); // 设置图片显示位置
image.scalePercent(12); // 按照百分比缩放
pcb.addImage(image);
}
}else System.err.println("logo input stream is null.");
} catch (Exception e) {
System.err.println(e);
}
pcb.beginText(); // Header
float top = document.top(-15);
pcb.showTextAligned(PdfContentByte.ALIGN_RIGHT, "XX开放平台API文档", document.right(), top, 0);
// Footer
float bottom = document.bottom(-15);
pcb.showTextAligned(PdfContentByte.ALIGN_CENTER, "第 " + writer.getPageNumber() + " 页", (document.right() + document.left()) / 2, bottom, 0);
pcb.endText(); pcb.restoreState();
pcb.closePath();
}
}
/**
* POJO for init Data.
*/
static class Api { private String apiName;
private String apiDesc;
private List<Params> params; public String getApiName() {
return apiName;
}
public void setApiName(String apiName) {
this.apiName = apiName;
}
public String getApiDesc() {
return apiDesc;
}
public void setApiDesc(String apiDesc) {
this.apiDesc = apiDesc;
}
public List<Params> getParams() {
return params;
}
public void setParams(List<Params> params) {
this.params = params;
}
} /**
* POJO for init Data.
*/
static class Params { private String paramName;
private String paramType;
private String paramDesc; public String getParamName() {
return paramName;
}
public void setParamName(String paramName) {
this.paramName = paramName;
}
public String getParamType() {
return paramType;
}
public void setParamType(String paramType) {
this.paramType = paramType;
}
public String getParamDesc() {
return paramDesc;
}
public void setParamDesc(String paramDesc) {
this.paramDesc = paramDesc;
}
}
}

注意:

所需jar包(itext5.0以下的包路径是com.lowagie.text,与后续版本不一致,并且直接引用中文itext-asian.jar的时候会因为lowagie名称造成路径错误,导致中文引入失败):

itext-5.0.2.jar, itext-asian-5.1.1.jar

也可以是itextpdf-5.5.5.jar, itext-asian-5.2.0.jar(下载)(建议使用),注意搭配不要错误。搭配的依赖原则是itext.jar或者itextpdf.jar中com.itextpdf.text.pdf.CJKFont.java中load字体所用的路径,

itext-asian-5.1.1.jar的路径是com/itextpdf/text/pdf/fonts/cjkfonts.properties,对应itext-5.0.2.jar中CJKFont的load路径;

itext-asian-5.2.0.jar的路径是com/itextpdf/text/pdf/fonts/cmaps/cjk_registry.properties,对应itextpdf-5.5.5.jar中CJKFont的load路径。

最终效果:

itextpdf JAVA 输出PDF文档的更多相关文章

  1. Servlet输出PDF文档方法

    概述 Java Servlet 编程可以很方便地将 HTML 文件发送到客户端的 Web 浏览器.然而许多站点还允许访问非 HTML 格式的文档,包括 Adobe PDF.Microsoft Word ...

  2. Java生成PDF文档(表格、列表、添加图片等)

    需要的两个包及下载地址: (1)iText.jar:http://download.csdn.net/source/296416 (2)iTextAsian.jar(用来进行中文的转换):http:/ ...

  3. [开源框架推荐]Icepdf:纯java的pdf文档的提取和转换库

    ICEpdf 是一个轻量级的开源 Java 语言的 PDF 类库.通过 ICEpdf 可以用来浏览.内容提取和转换 PDF 文档,而无须一些本地PDF库的支持. 可以用来做什么? 1.从pdf文件中提 ...

  4. Java 在PDF文档中绘制图形

    本篇文档将介绍通过Java编程在PDF文档中绘制图形的方法.包括绘制矩形.椭圆形.不规则多边形.线条.弧线.曲线.扇形等等.针对方法中提供的思路,也可以自行变换图形设计思路,如菱形.梯形或者组合图形等 ...

  5. Java 设置PDF文档背景色

    一般生成的PDF文档默认的文档底色为白色,我们可以通过一定方法来更改文档的背景色,以达到文档美化以及保护双眼的作用. 以下内容提供了Java编程来设置PDF背景色的方法.包括: 设置纯色背景色 设置图 ...

  6. Java 设置PDF文档背景——单色背景、图片背景

    一般生成的PDF文档默认的文档底色为白色,我们可以通过一定方法来更改文档的背景色,以达到文档美化的作用. 以下内容提供了Java编程来设置PDF背景色的方法.包括2种设置方法: 设置纯色背景色 设置图 ...

  7. java读取pdf文档

    import java.io.*;import org.pdfbox.pdmodel.PDDocument;import org.pdfbox.pdfparser.PDFParser;import o ...

  8. Java 打印PDF文档的3种情况

    以下内容归纳了通过Java程序打印PDF文档时的3种情形.即: 静默打印 显示打印对话框打印 打印PDF时自定义纸张大小 使用工具:Spire.PDF for Java Jar导入: 方法1:通过官网 ...

  9. Java 设置PDF文档浏览偏好

    在查看PDF文档时,可进行一些浏览偏好设置,例如是否全屏浏览.隐藏或显示菜单栏/工具栏.设置页面布局模式等,下面将通过Java编程的方式来演示如何设置. 使用工具: Free Spire.PDF fo ...

随机推荐

  1. [MFC] 高仿Flappy bird 桌面版

    这是今年年初做的东西,一直没有时间整理,现在拿出来分享下~ 目录 开发背景 开发语言及运行环境 效果展示 游戏框架说明 游戏状态及逻辑说明 经典算法说明 重量级问题解决 开发感想 一.开发背景: fl ...

  2. Linux:文件解压与压缩

    文件打包与压缩 常见压缩文件格式: |文件后缀名 |说明| |.zip |zip程序打包压缩的文件| |.rar |rar程序压缩的文件| |.7z |7zip程序压缩的文件| |.tar |tar程 ...

  3. 深入了解javascript事件流

    摘要:事件流这个东西是比较重要的,为了让自己更加理解js中的事件流,必须整理整理,梳理一下事件流的各种东西啊.本文大部分内容参考<javascript高级程序设计第三版> 先来一段书里的原 ...

  4. Windows环境下32位汇编语言程序设计(典藏版)

    Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)(年,经典再现!) 罗云彬 著 ISBN 978-7-121-20759-4 2013年7月出版 定价:99.00元 756页 1 ...

  5. 测量行业(RTK)相关的小知识总结

    RTK测量系统,一般需要先架设基准站(参考站),数据链模式外挂大电台(有天线大功率模式,理想范围方圆18公里以内).基准站通过收到卫星(多星)进行计算出当前的位置. 其中涉及到频率的设置,波特率,以及 ...

  6. bind() live()和delegate 区别

    Event bubbling (aka event propagation)冒泡 我们的页面可以理解为一棵DOM树,当我们在叶子结点上做什么事情的时候(如click一个a元素),如果我们不人为的设置s ...

  7. 《Windows核心编程》学习笔记(9)– 在win7或者vista系统下提升一个进程的运行权限

    win7或者vista默认运行程序是在受限制的环境下运行的,以减轻病毒对于系统的破坏.那么我们怎样才能提升一个进程的权限以至让它在 管理员模式下运行.当然CreateProcess函数没有提供这个功能 ...

  8. 【Python排序搜索基本算法】之深度优先搜索、广度优先搜索、拓扑排序、强联通&Kosaraju算法

    Graph Search and Connectivity Generic Graph Search Goals 1. find everything findable 2. don't explor ...

  9. IE11企业模式介绍及可用性评估

    什么是企业模式? 企业模式是可以在 Windows 8.1 和 Windows7 设备上的 Internet Explorer 11 上运行的一种兼容性模式,该模式允许网站使用已修改的浏览器配置来呈现 ...

  10. Nginx开发从入门到精通 学习目录分享学习 (阿里著作)

    Nginx开发从入门到精通   缘起 nginx由于出色的性能,在世界范围内受到了越来越多人的关注,在淘宝内部它更是被广泛的使用,众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部 ...