渲染预览PDF文档,轻松搞定,这方案真香!

1.前言

在实际项目中,文档生成功能是较常用的需求.比如办单报告,缴费报告,合同文件之类等.生成相应office文档;可以在线预览文档,并支持打印下载.网上也有很多解决方案.今天我们就来聊一聊一种新的解决方案.在线动态PDF数据生成预览,一定让各位看客姥爷满意.

2.列举一些文档预览解决方案:

  • 直接引用微软提供的方法,在 https://view.officeapps.live.com/op/view.aspx?src= 后边添加需要预览的文档地址,方便简单且免费
  • pdf.js开源在线浏览工具,直接引入项目中,下载链接:http://mozilla.github.io/pdf.js/;下载下来的压缩包包含两个文件夹:build和web,打开web文件夹下的viewer.html,就能看到PDF的预览效果了。
  • easypoi 开源工具里支持对excel 等文档的在线预览.
  • https://file.keking.cn/index 开源文件预览 支持各类officce文档 图片 压缩包 等等.
  • 使用pdfobject.js实现在线浏览PDF,官网:https://pdfobject.com/
  • 付费产品预览方案有【永中office】【office365】【idocv】等.

3.列举一些文档解析生成解决方案:

  1. easypoi支持预览也支持根据模板动态生成文档.
  2. freemarker + word 实现动态文件生成; 受word版本影响,要office软件的word.
  3. jasperReports+ireport+java运用 还需下载工具,设计文档;较繁琐.
  4. wps开发者服务,支持在线编辑生成文档,很方便但是需要企业资质才能申请账号.
  5. java使用itext操作填充pdf模板 需要两个jar包 itext-asian-5.2.0.jar和 itextpdf-5.5.6.jar,编码复杂。

以上总结:

  1. 以上提到的关于预览文档和生成在线文档技术,我们不做过多研究,只是给大家例举一下.各类方案有各自的优势,之后有空再对各类实现方案进行单独讲解.
  2. 通过各类解决方案我们看到,动态生成文档的时候基本依赖于模板文档.只是通过动态数据替换值域.
  3. 今天我们要说的这种实现方案也是依赖于模板和freemarker技术实现.不同的就是这个模板的不同.

4.案列赏析

在讲解这个实现方案之前我们先来看一下小弟为各位看官提供的一些模板案列:

以上的模板都是都是依赖于一种XDOC标签,了解更多请看此文档:
Xdoc标签文档.
官网: http://www.xdocin.com/web.html.
官网中提供对office模板文档word,ppt,excel 设计指南,预览生成指南.但是需要付费购买服务才能分发秘钥.调用服务.今天我们讲解这种pdf 生成方案完全免费试用.

那么我们以个人资料在线模板为主进行展开讲解.

5.准备工作:

freemarker 中文官方参考手册 http://freemarker.foofun.cn/

  1. 项目中引入freemarker配置:
   <!--freemarker-->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-freemarker</artifactId>
       </dependency>
  1. freemarker 基本yml 配置:
 freemarker:
     template-loader-path: classpath:/templates/
     suffix: .ftl
     charset: utf-8
     default-encoding: utf-8
     content-type: text/html;charset=utf-8
     #设定所有request的属性在merge到模板的时候,是否要都添加到model中
     expose-request-attributes: true
     #设定所有HttpSession的属性在merge到模板的时候,是否要都添加到model中.
     expose-session-attributes: true
     #设定是否以springMacroRequestContext的形式暴露RequestContext给Spring’s macro library使用
     expose-spring-macro-helpers: true
     #指定RequestContext属性的名.
     request-context-attribute: request
     #缓存
     cache: false
     settings:
          #重新加载模版文件 间隔时间
          template_update_delay: 10
          #中文
          locale: zh_CN
          #日期-时间格式化
          datetime_format: yyyy-MM-dd HH:mm:ss
          #日期格式化
          date_format: yyyy-MM-dd
          #数字格式化
          number_format: #.####
          #兼容传统模式
          classic_compatible: true
          #忽略异常配置
          template_exception_handler: ignore

3.xdoc pom配置引入:

 <dependency>
           <groupId>com.hg.xdoc</groupId>
           <artifactId>xdoc</artifactId>
           <version>X.1.0.0</version>
 </dependency>

备注:此包已上传到gitee项目doc目录下.

6.模板讲解:

pdf预览模板实际就是一个freemarker 模板,以页面根标签xdoc为主的一系列标签元素组合.以个人资料模板作为解读.如下效果图所示:

在这里插入图片描述
我们看到此文档主要是表格table的组合.页面元素如下很多属性很HTML一样.
在这里插入图片描述
对应文档讲解如下 请认真阅读上面Xdoc文档:
在这里插入图片描述
只要对前段页面标签html了解的小伙伴很快就能熟悉入手这些标签.因此对于模板设计这一块门槛还是很低的,易上手.
在这里插入图片描述
数据渲染完全遵循freemarker 解析语法.

7.代码实现:

文档生成的场景有很多,我们给一个简单的案例,用于个人资料展示.
在这里插入图片描述
这是前段文档预览入口.后端我们就需要考虑如何将个人用户数据封装到模板文件里,然后通过控制层展示出来.请看代码:

  1. 首先加载模板文件jianli.ftl:
 InputStream inputStream = this.getClass().getResourceAsStream("/templates/jianli.ftl");
 content = createTemplateView(user, inputStream);
  1. 封装数据调map 传递到freemarker 模板解析:
 //设置模板变量
 Map<String, Object> map = new HashMap<>(16);
 map.put("model", user);
 //获取年份
 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
 Date date = new Date();

 map.put("date", sdf.format(date));
 String fileName = "jianli.ftl";
 String content = FreeMarkerUtil.templateAnalysis(map, inputStream, fileName);
  1. freemarker 解析数据生成固定模板数据:
  //创建配置实例 Configuration
 Configuration cfg = new Configuration(Configuration.VERSION_2_3_25);
 cfg.setDefaultEncoding("utf-8");

 //读取到根目录
 InputStreamReader isr = null;
 BufferedReader br = null;

 StringBuffer stringBuffer = new StringBuffer();
 try {
     isr = new InputStreamReader(inputStream,"utf-8");
     br = new BufferedReader(isr);

     String lineStr = "";
     while ((lineStr = br.readLine()) != null) {
         stringBuffer.append(lineStr);
     }
 } catch (Exception e) {
     logger.error(e.toString());
 } finally {
     br.close();
     isr.close();
 }
 StringTemplateLoader stl = new StringTemplateLoader();
 String fileName = templateFile.replace("ftl", "");
 stl.putTemplate(fileName, stringBuffer.toString());

 cfg.setTemplateLoader(stl);

 //工程目录下的目录
//            cfg.setDirectoryForTemplateLoading(file);

 //获取模板(template)
 Template template = cfg.getTemplate(fileName);

 //获取输出流(指定到控制台(标准输出))
 StringWriter out = new StringWriter();

 //数据与模板合并(数据+模板=输出)
 template.process(root, out);

 content = out.toString();

 out.flush();
  1. 数据传输到view层:
	ModelAndView modelAndView = new ModelAndView("/preview");
	StringBuilder builder = new StringBuilder();
	//动态封装数据
	builder.append(templateResume(user));
	modelAndView.addObject("context", builder.toString());
 	return modelAndView;
  1. preview.ftl 展示出模板数据:
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <script type="text/javascript" src="/api/js/xdoc.js"></script>
</head>
<body style="height:100%; margin:0; overflow:hidden;">
<script id="myxdoc" type="text/xdoc" _format="pdf" style="width:100%;height:100%;">
    <xdoc version="11.1.5">
        <meta modifyDate="2017-08-15 14:45:10" author="Administrator" id="3ulahulfbrdwnfujnnjulqjcpm" title="在线预览" createDate="2017-08-15 12:37:46"/>
        <paper width="812" height="1124" topMargin="15" bottomMargin="15" leftMargin="61" rightMargin="71"/>
        <body>
            ${context}
        </body>
    </xdoc>
</script>
</script>
</body>
</html>
  1. 在preview.ftl 引入xdoc.js 文件内容如下 :
var XDoc = {};
//版本
XDoc.version = "A.3.3";
//XDocServer地址
XDoc.server = "/api/freemarker";
/**
 * 转换XDOC
 * @param xdoc xdoc模板
 * @param tarFormat 目标格式,可以是:pdf等
 * @param param 其它参数,用对象方式传递多个参数
 * @param target 目标类型,可以是:_blank、_self等
 */
XDoc.to = function(xdoc, tarFormat, param, target) {
	param['type']='preview';
	XDoc._invoke("to", xdoc, tarFormat, param, target);
};

  1. XDocServer地址 是需要我们设置的:
   @PostMapping("/xdoc")
   public void xdoc(HttpServletRequest request, HttpServletResponse response) throws IOException {
          String format = request.getParameter("_format");
           if (format == null) {
               format = "pdf";
           } else if (format.equals("jpg")) {
               format = "jpeg";
           }
           if (format.equals("pdf")) {
               response.setContentType("application/pdf");
           } else if ((format.equals("png")) || (format.equals("jpeg"))) {
               response.setContentType("image/" + format);
           } else {
               response.setContentType("text/xml;charset=utf-8");
           }
           XDoc.write(xdoc, out, format);
       out.flush();
       out.close();
   }

总结: 动态模板生成数据完美实现.

8.效果图:

我们看到数据已经动态渲染成功,在这里我们只渲染了个人资料,更多信息一样的渲染规则。
在这里插入图片描述
说明:这个pdf文档是在线预览的,可以选择性打印下载.不用生成文件后才能预览.

9.打印效果图:

在这里插入图片描述

10.体验:

以上项目案列体验地址如下:

有料后台管理系统
账号: guest
密码: guest
案例项目源码地址

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: POI(Poor Obfuscation Implementation)是一个开源的Java类库,用于处理Microsoft Office格式的文档,如Word、Excel和PowerPoint。然而,POI并不直接支持PDF文件的预览和转换,因为PDF文件属于Adobe的专有格式。 要在Java中实现PDF预览和转换,可以使用其他的开源库,如Apache PDFBox或iText。Apache PDFBox提供了处理PDF文件的功能,包括预览、提取文本、提取图像等。iText则提供了PDF文档的创建、修改和转换功能。 使用Apache PDFBox预览PDF文件时,可以使用PDFRenderer类来将PDF文件渲染成图像,然后将图像显示在用户界面上。此外,PDFBox还提供了一些其他的工具方法,如提取文本、切割页面、合并多个PDF文件等。 要将PDF文件转换为文档预览,可以使用iText库。iText提供了将PDF文件转换成其他格式(如文本、HTML、图像)的功能。可以使用PdfReader类读取PDF文件,然后使用PdfDocument类将其转换成所需的格式,并保存到文件或以流的形式输出。 综上所述,POI库本身不支持PDF文件的预览和转换,但可以通过使用其他的开源库,如Apache PDFBox或iText,来实现这些功能。这些库提供了对PDF文件的处理和转换的API,可以方便地在Java中实现PDF预览和转换。 ### 回答2: POI(即Apache POI)是Java编程语言的开源库,用于处理各种Office文档格式。它包括对Word、Excel和PowerPoint等文件的读写操作。然而,POI本身不支持直接预览PDF文件。 要在Java预览PDF文件,我们可以借助第三方库或工具。其中一种常用的选择是使用Apache PDFBox。 Apache PDFBox是一个功能强大的Java库,用于处理和操作PDF文件。它提供了许多功能,包括读取、写入和编辑PDF文件,以及提取文本、图像和元数据等。 要使用Apache PDFBox预览PDF文件,我们可以通过以下步骤实现: 1. 使用PDFBox库加载PDF文件。我们可以使用`PDDocument.load()`方法来加载指定路径下的PDF文件。 2. 获取PDF页面数。通过使用`getNumberOfPages()`方法,我们可以获得PDF文件中的页面总数。 3. 选择要预览的页面。我们可以使用`getPage(int pageNumber)`方法获取指定页码的页面内容。 4. 将页面内容转换为图像。PDF页面必须先转换为图像才能在Java应用程序中进行预览。我们可以使用`PDFRenderer`类的`renderImage(int pageIndex)`方法将页面渲染为图像。 5. 将图像显示在Java应用程序中。我们可以使用Java图形库(如AWT或JavaFX)的API来显示图像,并以预览方式呈现PDF内容。 通过这些步骤,我们可以使用POI和PDFBox这两个开源库来实现在Java应用程序中预览PDF文件。这样,我们可以读取PDF文件的内容,并将其在应用程序中以图像的形式显示,以达到预览的效果。 ### 回答3: POI(Poor Obfuscation Implementation)是一个Java开发库,用于处理各种办公文档,如Microsoft Office(包括Word、Excel和PowerPoint)和Adobe PDF文件。而预览PDF文件和转换为文档预览是POI库的其中一个功能。 在使用POI预览PDF文件时,首先需要引入POI的相关依赖包,并在代码中创建一个PDF文档的输入流。然后,使用POI提供的API,将输入流加载到POI的对象中。接下来,可以通过遍历PDF页面,将页面的内容提取出来进行展示。这样就可以实现PDF文件的预览功能。 转换为文档预览是指将PDF文件转换为其他格式的文档,并进行预览展示。POI库提供了一些转换功能,可以将PDF文件转换为其他格式的文档,如Word文档或HTML文件等。具体的转换过程类似于预览功能,需要加载PDF文件并进行内容提取和格式转换。 POI库是一个功能强大的处理办公文档的工具,可以方便地进行PDF文件的预览和转换为其他格式的文档。它不仅提供了对PDF文件的读取和写入功能,还支持对PDF文件的内容提取、文本搜索、页面拆分等操作。无论是需要进行PDF文件的预览,还是将PDF文件转换为其他格式的文档,使用POI库都能轻松地实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值