前言:没有自己动手实践的代码你永远不知能不能用,前路漫漫,总要有人投石问路,才能放心复制粘贴,废话不多说了,直接上代码,请诸君掌眼!
1.spire for pdf
并非开源,需要付费,测试版有水印,估计大多数用户会弃之如敝履
<!--spire-->
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.pdf.free</artifactId>
<version>3.9.0</version>
</dependency>
<!--仓库地址-->
<repository>
<id>com.e-iceblue</id>
<url>http://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
@Test
public void userSpireToPdf() {
//定义需要转换的HTML(直接一个html页面是行不通的,可以访问的地址页面)
String url = "http://localhost:8000/project/Doc";
//转换后的结果文档(结果文档保存在Java项目程序文件下)
String fileName = "C:\\Users\\admin\\Desktop\\新建文件夹\\spireToPdf.pdf";
//解压后的插件本地地址(这里是把插件包放在了Java项目文件夹下,也可以自定义其他本地路径)
String pluginPath = "D:\\plugins-window64";
HtmlConverter.setPluginPath(pluginPath);
//调用方法转换到PDF并设置PDF尺寸
HtmlConverter.convert(url, fileName, true, 1000, new Size((float) PdfPageSize.A4.getWidth(), (float) PdfPageSize.A4.getHeight()), new Pd
fMargins(0)); }
导出的pdf我就不给各位看官贴了,想测试可以把url换成百度之类的地址
2.itext
itex对html页面的样式,标签的闭合,字体的
<!--itext to pdf-->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.9</version>
</dependency>
@Test
public void testItextToPdf() {
StringBuilder strline = new StringBuilder("");
File fin = new File("C:\\Users\\admin\\Desktop\\新建文件夹\\htmltopdf.html");
try (RandomAccessFile accessFile = new RandomAccessFile(fin, "r");
FileChannel fcin = accessFile.getChannel();
) {
Charset charset = Charset.forName("UTF-8");
int bufSize = 100000;
ByteBuffer rBuffer = ByteBuffer.allocate(bufSize);
String enterStr = "\n";
byte[] bs = new byte[bufSize];
StringBuilder strBuf = new StringBuilder("");
while (fcin.read(rBuffer) != -1) {
int rSize = rBuffer.position();
rBuffer.rewind();
rBuffer.get(bs);
rBuffer.clear();
String tempString = new String(bs, 0, rSize, charset);
tempString = tempString.replaceAll("\r", "");
int fromIndex = 0;
int endIndex = 0;
while ((endIndex = tempString.indexOf(enterStr, fromIndex)) != -1) {
String line = tempString.substring(fromIndex, endIndex);
line = strBuf.toString() + line;
strline.append(line.trim());
strBuf.delete(0, strBuf.length());
fromIndex = endIndex + 1;
}
if (rSize > tempString.length()) {
strline.append(tempString.substring(fromIndex, tempString.length()));
strBuf.append(tempString.substring(fromIndex, tempString.length()));
} else {
strline.append(tempString.substring(fromIndex, rSize));
strBuf.append(tempString.substring(fromIndex, rSize));
}
}
String htmlString = "";
htmlString = strline.toString().replaceAll("\"", "'").replaceAll("<style>", "<style>body{font-family:SimSun;font-size:14px;}"); //注意这里为啥要写这个,主要是替换成这样的字体,如果不设置中文有可能显示不出来。
OutputStream os = new FileOutputStream("C:\\Users\\admin\\Desktop\\新建文件夹\\itextToPdf.pdf"); //生成PDF文件的路径
ITextRenderer renderer = new ITextRenderer();
ITextFontResolver font = renderer.getFontResolver();
font.addFont("C:/WINDOWS/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);//添加中文识别,这里是设置的宋体,Linux下要换成对应的字体
renderer.setDocumentFromString(htmlString.toString());
renderer.layout();
renderer.createPDF(os);
renderer.finishPDF();
} catch (Exception e) {
System.out.println(e);
}
}
html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>认识table表标签</title>
<style type="text/css">
/*解决html转pdf文件中文不显示的问题*/
body {
font-family: SimSun;
}
/*设定纸张大小*/
/* A4纸 */
/* @page{size:210mm*297mm} */
@page{size:a4}
p {
color: red;
}
</style>
</head>
<body>
<table border="1px">
<caption>我的标题</caption>
<tbody>
<tr>
<th>班级</th>
<th>学生数</th>
<th>平均成绩</th>
<th>班级</th>
<th>学生数</th>
<th>平均成绩</th>
<th>班级</th>
<th>学生数</th>
<th>平均成绩</th>
</tr>
<tr>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
</tr>
<tr>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
</tr>
<tr>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
</tr>
</tbody>
</table>
<p>
《侠客行》<br/>
年代: 唐 作者: 李白<br/>
赵客缦胡缨,吴钩霜雪明。银鞍照白马,飒沓如流星。<br/>
十步杀一人,千里不留行。事了拂衣去,深藏身与名。<br/>
闲过信陵饮,脱剑膝前横。将炙啖朱亥,持觞劝侯嬴。<br/>
三杯吐然诺,五岳倒为轻。眼花耳热后,意气素霓生。<br/>
救赵挥金槌,邯郸先震惊。千秋二壮士,煊赫大梁城。<br/>
纵死侠骨香,不惭世上英。谁能书閤下,白首太玄经。<br/>
</p>
<img src="https://tpc.googlesyndication.com/simgad/17749066154578206954"/>
</body>
</html>
效果:
3.Flying saucer +itext
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.13</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>
@Test
public void useFlyingSaucerToPdf() throws IOException {
String pdfName = "项目立项报告 .pdf";
String htmlStr = readFileToString(new File("C:\\Users\\admin\\Desktop\\新建文件夹\\a.html"));
this.htmlToPdf(htmlStr, pdfName, "C:\\Windows\\Fonts");
}
private String readFileToString(File fin) throws IOException {
StringBuilder strline = new StringBuilder("");
try (RandomAccessFile accessFile = new RandomAccessFile(fin, "r");
FileChannel fcin = accessFile.getChannel();
) {
Charset charset = Charset.forName("UTF-8");
int bufSize = 100000;
ByteBuffer rBuffer = ByteBuffer.allocate(bufSize);
String enterStr = "\n";
byte[] bs = new byte[bufSize];
StringBuilder strBuf = new StringBuilder("");
while (fcin.read(rBuffer) != -1) {
int rSize = rBuffer.position();
rBuffer.rewind();
rBuffer.get(bs);
rBuffer.clear();
String tempString = new String(bs, 0, rSize, charset);
tempString = tempString.replaceAll("\r", "");
int fromIndex = 0;
int endIndex = 0;
while ((endIndex = tempString.indexOf(enterStr, fromIndex)) != -1) {
String line = tempString.substring(fromIndex, endIndex);
line = strBuf.toString() + line;
strline.append(line.trim());
strBuf.delete(0, strBuf.length());
fromIndex = endIndex + 1;
}
if (rSize > tempString.length()) {
strline.append(tempString.substring(fromIndex, tempString.length()));
strBuf.append(tempString.substring(fromIndex, tempString.length()));
} else {
strline.append(tempString.substring(fromIndex, rSize));
strBuf.append(tempString.substring(fromIndex, rSize));
}
}
String htmlString = "";
htmlString = strline.toString().replaceAll("\"", "'").replaceAll("<style>", "<style>body{font-family:SimSun;font-size:14px;}");
return htmlString;
}
}
private void htmlToPdf(String html, String pdfName, String fontDir) {
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
// 解决中文支持问题
ITextRenderer renderer = new ITextRenderer();
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont("C:/Windows/fonts/SimSun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//
// ITextFontResolver fontResolver = (ITextFontResolver) renderer.getSharedContext().getFontResolver();
// //添加字体库 begin
// File f = new File(fontDir);
// if (f.isDirectory()) {
// File[] files = f.listFiles(new FilenameFilter() {
// public boolean accept(File dir, String name) {
// String lower = name.toLowerCase();
// return lower.endsWith(".otf") || lower.endsWith(".ttf") || lower.endsWith(".ttc");
// }
// });
// for (int i = 0; i < files.length; i++) {
// fontResolver.addFont(files[i].getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
// }
// }
//添加字体库end
renderer.setDocumentFromString(html);
renderer.layout();
renderer.createPDF(os);
renderer.finishPDF();
byte[] buff = os.toByteArray();
//保存到磁盘上
byte2File(buff, "C:\\Users\\admin\\Desktop\\新建文件夹\\", pdfName);
} catch (Exception e) {
e.printStackTrace();
}
}
private byte[] file2Byte(String filePath) {
ByteArrayOutputStream bos = null;
BufferedInputStream in = null;
try {
File file = new File(filePath);
if (!file.exists()) {
throw new FileNotFoundException("file not exists");
}
bos = new ByteArrayOutputStream((int) file.length());
in = new BufferedInputStream(new FileInputStream(file));
int buf_size = 1024;
byte[] buffer = new byte[buf_size];
int len = 0;
while (-1 != (len = in.read(buffer, 0, buf_size))) {
bos.write(buffer, 0, len);
}
return bos.toByteArray();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
return null;
} finally {
try {
if (in != null) {
in.close();
}
if (bos != null) {
bos.close();
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
private void byte2File(byte[] bfile, String filePath, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
try {
File dir = new File(filePath);
if (!dir.exists() && !dir.isDirectory()) {//判断文件目录是否存在
dir.mkdirs();
}
file = new File(filePath + fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bfile);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
} finally {
try {
if (bos != null) {
bos.close();
}
if (fos != null) {
fos.close();
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
flying saucer 是基于itext的,对css样式有更好的支持,我是没耐心写测试复杂的html页面 ,测试能用
html页面指定字体,不然不识别汉字,毕竟是!Chinese开发的
<head>
<style type="text/CSS">
body{font-family:"SimSun"}
</style>
</head>
4.git上找的项目,用freemark+itext+flyingsaucer+模板实现的
我贴关键代码,给你们github链接,下载之后把jdk版本改一下可以用:https:///youzhibing/itextpdf
代码我就不贴了,给你们看一下效果吧