近期由于工作需要,需要将html代碼導入到pdf中,經過了幾種pdf的方案對比後發現IText是最簡單和便捷的一種方式,于是乎采用了Itext。
PDF生成
第一步:導入Maven依賴
<!--pdf生成工具類-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.4.1</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.0.3</version>
</dependency>
第二步:直接上代碼
public static void main(String[] args) throws IOException
{
String html = PDFKit.readFileByUrl("http://127.0.0.1/export/1/1"); // 将html代碼讀取到html字元串中
try {
Document document = new Document();
PdfWriter mPdfWriter = PdfWriter.getInstance(document, new FileOutputStream(new File("C:\\data\\3.pdf")));
document.open();
ByteArrayInputStream bin = new ByteArrayInputStream(html.getBytes());
XMLWorkerHelper.getInstance().parseXHtml(mPdfWriter, document, bin, null, new ChinaFontProvide());
System.out.println("生成完畢");
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static final class ChinaFontProvide implements FontProvider
{
@Override public boolean isRegistered(String s)
{
return false;
}
@Override public Font getFont(String arg0, String arg1, boolean arg2, float arg3, int arg4, BaseColor arg5)
{
BaseFont bfChinese = null;
try
{
bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
}
catch(Exception e)
{
e.printStackTrace();
}
Font FontChinese = new Font(bfChinese, 12, Font.NORMAL);
return FontChinese;
}
}
另附PDFKit.java工具類
public static String readFileByUrl(String urlStr) {
String res=null;
try {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//設定逾時間為3秒
conn.setConnectTimeout(3*1000);
//防止屏蔽程式抓取而傳回403錯誤
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
//得到輸入流
InputStream inputStream = conn.getInputStream();
res = readInputStream(inputStream);
} catch (Exception e) {
log.error("通過url位址擷取文本内容失敗 Exception:" + e);
}
return res;
}
/**
* 從輸入流中擷取字元串
* @param inputStream
* @return
* @throws IOException
*/
public static String readInputStream(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
//System.out.println(new String(bos.toByteArray(),"utf-8"));
return new String(bos.toByteArray(),"utf-8");
}
至此 dpf就可以到下面路徑中檢視了
C:\\data\\3.pdf
PDF預覽
隻需在頁面中增加如下代碼即可
<html>
<head>
<title>Title</title>
</head>
<body>
<body style="height: 100%; width: 100%; overflow: hidden; margin: 0px;">
<embed width="100%" height="100%" src="pdf/3.pdf" type="application/pdf" internalinstanceid="25"/>
</body>
</body>
</html>
注意:html文檔一定是<html>,不可以是<!DOCTYPE html> 不然body的100% 會失去效果
預覽效果

特别說明
如上代碼生成的pdf,如果直接用工具打開後發現字型是沒有問題,但是嵌套在網頁後發現字型竟然不是宋體了,下面我們來介紹下IText輸出中文的三種字型的選擇方式
1、使用iTextAsian.jar中的字型
BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
2、使用Windows系統字型(TrueType)
BaseFont.createFont("C:/WINDOWS/Fonts/SIMLI.TTF", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
3、使用資源字型(ClassPath)
BaseFont.createFont("/SIMYOU.TTF", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED); //下面着重介紹
上面是設定字型的方式,剛剛咱們用的第一種方式,是以pdf預覽的的時候字型會變,改用下面的方式就沒有任何問題了,下面咱們說下标紅的是什麼意思
由于項目使用的是springboot,是以釋出到liunx後并不能直接從jar中查找相應的字型,要改用ClassPathResource的方式擷取,是以更換代碼如下:
ClassPathResource resource = new ClassPathResource("static/STSONG.TTF");
bfChinese = BaseFont.createFont(resource.getURL().toString(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
可将STSONG.TTF直接放入resources檔案夾根目錄即可
這樣windows和linux都可以正确的生成pdf并預覽了。更換後的效果:
另附:常用字型
//楷體字
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//simkai.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//方正舒體
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//FZSTK.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//方正姚體
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//FZYTK.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//仿宋體
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMFANG.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//黑體
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//華文彩雲
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STCAIYUN.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//華文仿宋
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STFANGSO.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//華文細黑
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STXIHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//華文新魏
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STXINWEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//華文行楷
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STXINGKA.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//華文中宋
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STZHONGS.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//隸書
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMLI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);//宋體-方正超大字元集
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SURSONG.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//幼圓
BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMYOU.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
開開心心編碼,快快樂樂生活。