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>中的文字溢出,滚动条隐藏掉的内容也能出来了

如果有更好的办法欢迎指点

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值