java将部分网页内容转为pdf文件并导出
描述
由于数据过多,需求是要将展示出来的内容导出为pdf文件,最初经大佬指点,采用的是前端的html2canvas和jsPDF,做出来之后各种问题,显示不全、文字重叠、溢出、内容截断,无奈改用java来做,记录如下解决办法
要转为pdf在页面展示的内容
前端代码
<div class="reportContent">
<div id="renderPdf" v-html="htmlContent"></div>
</div>
<div slot="footer">
<Button @click="delReport()">删除</Button>
<Button @click="modifyReport()">修改</Button>
<Button>
<a :href="pdfUrl" download>导出</a>
</Button>
<Button @click="showSMS()">发送短信</Button>
<Button @click="showVoice()">发送语音</Button>
</div>
此处的 htmlContent 是展示在页面上的内容,要将它转为pdf文件,小白事先将它存到数据库里面,保存成功后把 id 返回过来,下面的 rep.data 就是 id
this.pdfUrl = config.baseUrl + "htmlToPdf/createFile?id=" + rep.data;
引入maven依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.9</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-itext5</artifactId>
<version>9.0.3</version>
</dependency>
controller层
@RequestMapping(value = "/createFile")
public void createFile(HttpServletResponse response,Integer id) {
//通过id将存到数据库的网页内容取出来
String fileContent = service.selectById(id).getContent();
try {
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=" + new Date().getTime() + ".pdf");
//将生成的pdf文件获取过来
File pdfFile = htmlToPdfUtil.createFile(fileContent);
//读写操作,将文件传到前台导出
OutputStream os = response.getOutputStream();
InputStream is = new FileInputStream(pdfFile);
byte[] buffer = new byte[is.available()];
is.read(buffer);
is.close();
os.write(buffer);
os.close();
//完成后把文件删除
pdfFile.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
工具类
如果页面内容中有
<pre>
的话将
“pre {font-family: SimSun;white-space:pre-wrap;}\r\n”
加到 String head 中
public class HtmlToPdfUtil {
//先把获取到的网页内容重新生成一个html文件
public File createFile(String fileContent) throws Exception {
File htmlFile = new File("." + File.separator + "app/static/document/temp.html");
File pdfFile = new File("." + File.separator + "app/static/document/temp.pdf");
FileOutputStream fos = null;
String head = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n"
+ "<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">\r\n" + "<head>\r\n"
+ "<meta charset=\"UTF-8\" />\r\n"
+ "<meta name=\"viewport\" content=\"initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width\"/>"
+ "<style>\r\n" + "table {border-collapse: collapse;table-layout: fixed;word-break:break-all;}\r\n"
+ "th,td {word-break:break-all;word-wrap : break-word;}\r\n"
+ "pre {font-family: SimSun;white-space:pre-wrap;}\r\n"
+ "@page {size:210mm 297mm;margin: 0.25in;-fs-flow-bottom: \"footer\";-fs-flow-left: \"left\";-fs-flow-right: \"right\";padding: 1em;}\r\n"
+ "</style>\r\n" + "</head>\r\n" + "<body style = \"font-family: SimSun;\">\r\n"
+ "<div>";
String foot = "\r\n</div>\r\n</body>\r\n</html>";
if (!htmlFile.exists()) {
htmlFile.createNewFile();
}
if (!pdfFile.exists()) {
pdfFile.createNewFile();
}
fos = new FileOutputStream(htmlFile);
String content = head + fileContent + foot;
fos.write(content.getBytes("utf-8"));
fos.flush();
fos.close();
html2pdf(htmlFile, pdfFile);
return pdfFile;
}
//将html文件转为pdf
public void html2pdf(File htmlFile, File pdfFile) throws Exception{
String url;
OutputStream os;
url = htmlFile.toURI().toURL().toString();
os = new FileOutputStream(pdfFile);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.layout();
renderer.createPDF(os);
os.close();
htmlFile.delete();
}
效果
虽然还是有隔断的现象,但是文字没有出现被“切成两半”的样子,也没有重叠和
<pre>
中的文字溢出,滚动条隐藏掉的内容也能出来了
如果有更好的办法欢迎指点
版权声明:本文为qq_39515385原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。