欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

动态jsp转pdf文件

程序员文章站 2022-07-06 23:32:07
...
最近需要做一个功能,把jsp页面转成pdf,jsp页面有动态填充的数据,网上找了一些资料,基本上都是纯html页面数据转pdf,达不到动态填充数据的要求,结合网上查询的资料,动手改造一下jsp动态数据转pdf并下载文件。


首先准备需要依赖的maven包和字体文件。

<dependency>
    <groupId>org.xhtmlrenderer</groupId>
    <artifactId>core-renderer</artifactId>
    <version>R8</version>
</dependency>

字体文件:simsun.ttc


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.http.HttpServletResponse;

import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;

/**
 * html转pdf工具
 *
 */
public class TtmlToPdfUtil {
	
	/**
	 * 把URL转换为PDF
	 * @param url 需要生成pdf的页面url
	 * @param filePath  生成的pdf存放目录
	 */
	public static void htmlToPdf(String url, String filePath){
		try {
			File outFile = new File(filePath);
			if (!outFile.exists()) {
				outFile.getParentFile().mkdirs();
			}
			OutputStream os = new FileOutputStream(filePath);
			ITextRenderer renderer = new ITextRenderer();
			renderer.setDocument(url);
			String fontPath = "/simsun.ttc";//字体
			// 解决中文支持问题
			ITextFontResolver fontResolver = renderer.getFontResolver();
			fontResolver.addFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
			renderer.layout();
			renderer.createPDF(os);
			os.flush();
			os.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 下载
	 * @param response
	 * @param filePath 
	 */
	public static void downloadPdf(HttpServletResponse response, String filePath) {
		try {
			File file = new File(filePath);
			InputStream inputStream = new FileInputStream(file);
			OutputStream os = response.getOutputStream();
			byte[] b = new byte[1024];
			int length;
			while ((length = inputStream.read(b)) > 0) {
				os.write(b, 0, length);
			}
			inputStream.close();
			
			file.delete();//下载完后删除
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}


调用的方法:
/**
	 * 下载
	 * @param request
	 * @param response
	 * @param stuId
	 * @throws Exception 
	 */
	@RequestMapping("/downStuPdf")
	public void downpdf(HttpServletRequest request, HttpServletResponse response,Integer stuId) throws Exception{
		Student stu = stuService.get(stuId);
		String fileName = stu.getName+".pdf";//生成的文件名称
		response.setCharacterEncoding("UTF-8");//设置相应内容的编码格式
		response.setHeader("Content-Disposition","attachment;filename="+new String(fileName.getBytes("GBK"), "ISO8859-1"));
		response.setContentType("application/pdf");//定义输出类型
		//http://127.0.0.1:8080/stu/getStuInfo.do
		TtmlToPdfUtil.htmlToPdf(ServerContext.getLocalUrl()+"getStuInfo.do?stuId="+stuId, fileName);
		TtmlToPdfUtil.downloadPdf(response, fileName);
	}
	
	/**
	 * 动态赋值信息到页面
	 * @return
	 */
	@RequestMapping("/getStuInfo")
	public ModelAndView stuInfo(Integer stuId) {
		Map<String, Object> map = new HashMap<String, Object>();
		//姓名和年龄从数据库取,这里测试
		// Student stu = stuService.get(stuId);
		map.put("name", "张三");
		map.put("age", 20);
		return new ModelAndView("student.jsp", map);
	}



上面下载的方法中,使用了两步,第一步先把需要生成pdf的页面生成文件后存放在某个磁盘目录,再然后从磁盘里下载文件,有兴趣的朋友可以尝试下能否直接在生成pdf的时候输出到浏览器下载文件。服务端动态取出数据后,jsp页面采用el表达式设置相应的值即可。字体文件太大,系统上传不了,自行网上下载。
这里有个坑提示下大家,转成pdf的页面如果一行文字太长,最后生成的pdf会自动截断后面显示不下的文字,这里提供一个勉强的解决方案,在jsp页面<head>标签中写如下样式,即生成的pdf默认为A4纸的尺寸,可以让文字显示全一些。也可以设置为A1,A2,但是好像并没什么作用,网上查了一些资料说是要修改源码包代码,重新自定义大小,比较麻烦。另外待生成的页面必须严格遵守w3c规范,标签必须关闭,否则生成一定出错。

<style>
body{font-family:SimSun;}
@page{size:A4;margin:0;}
</style>
  • 动态jsp转pdf文件
            
    
    博客分类: 笔记 jsp转pdfhtml转pdf
  • 大小: 17.1 KB