文档格式转换引擎开辟:支持PDF与OFD的技术实现

打印 上一主题 下一主题

主题 1009|帖子 1009|积分 3027

最新技术资源(发起收藏)
https://www.grapecity.com.cn/resources/
  媒介
近年来,中国在信息技术领域连续寻求自主创新和供应链安全,陪同信创上升为国家战略,一些行业也开始明确要求文件导出的格式必须为 OFD 格式。OFD 格式目前在政府、金融、税务、教诲、医疗等需要文件开放、共享和恒久生存的行业中广泛应用。这种趋势在将来几年内将进一步增强。
相较于 PDF,OFD 在以下方面展现了显着的上风,详细体现在:


  • 开放性
PDF 是 Adobe 公司开辟的专有格式,虽然也被广泛应用,但受制于 Adobe 公司的软件和许可。OFD 则是基于国际开放标准制定的开放式文档格式,任何人或组织都可以自由使用和开辟相关软件。


  • 功能特性
PDF 重要用于文档展示和打印,功能较为单一。OFD 在文档展示、打印、编辑等方面都有更强盛的功能支持。


  • 文件巨细
PDF 文件通常会略大于 OFD 文件,因为 PDF 包含更多的元数据和功能,OFD 文件在保持精良的视觉效果的前提下,通常体积更小。


  • 兼容性
PDF 虽然跨平台性强,但在不同软件和体系中的表现大概会有差别,OFD 则具有更好的跨平台划一性。


  • 安全性
PDF 文件大概包含隐蔽的功能和潜伏的安全隐患,OFD 则更加透明,安全性更高。
如何将 PDF 转化为 OFD?
既然导出 OFD 格式如此告急,然而目前市面上的报表工具,前端导出时通常只支持 PDF 格式。那么在这种环境下,如何实现一键在前端将报表导出为 OFD 格式呢?今天,小编将以葡萄城的嵌入式 BI 工具——Wyn 贸易智能作为例子,向大家先容如何将 PDF 转换为 OFD 格式。

首先小编先带大家一起相识下OFD文件解析的底层原理:
OFD 文件底层结构:
OFD 文件采用XML作为其根本结构,这意味着文件内容是以文本情势存储的,便于编辑和搜刮。OFD 文件重要由以下几个部分组成:

  • 文档头(Document Header):包含文档的根本信息,如标题、作者、创建日期等。
  • 文档体(Document Body):包含文档的实际内容,如文字、图片、表格等。
  • 资源文件(Resource Files):包括文档中使用到的图片、字体、样式等资源。
  • 元数据(Metadata):提供有关文档内容的额外信息,如关键词、摘要等。

PDF 转换为 OFD 的流程:

首先,通过使用 Wyn 报表工具,可以轻松计划出符合需求的报表样式。这些报表样式可以包含各种元素,比方表格、图表、图片、文本、超链接等等。计划完成后,可以直接在 Web 端进行预览,同时还支持将报表导出为PDF 格式。如许的计划流程和功能使得报表的创建和预览变得更加便捷和直观。

前端支持 PDF 导出只是第一步,为了实现从 PDF 转换为 OFD,还需要前端提供导出 PDF 的 API 接口,以便前端能够获取到 PDF 文件的流数据。荣幸的是,Wyn 提供了丰富的 API 接口,使得前端可以通过接口直接实现PDF 的导出功能。如许的计划使得 PDF 转换为 OFD 变得更加便捷和可行。
PDF 转 OFD 的实现步骤
前端导出PDF文件的API接口:
http://localhost:51980/api/v2/reporting/export-templates/{exportTemplateId}
后端进行PDF文件解析的方法

  • 继承 PDFGraphicsStreamEngine 类,便于分析 PDF 数据图层和资源归类
  1. public class OFDPageDrawer extends PDFGraphicsStreamEngine {
  2. }
复制代码

  • 重写构造方法,分析 PDF 每页的资源,并初始化 OFD 生成器
  1. /**
  2. 构造器,调用super(page),这个操作的目的是将page资源准备好,并且添加对应的操作符,
  3. 当下一次调用processPage或者processPageContentStream时执行对应的操作符对应的操作
  4. @param idx
  5. @param page
  6. @param ofdCreator
  7. @param scale
  8. @throws IOException
  9. */
  10. protected OFDPageDrawer(int idx, PDPage page, OFDCreator ofdCreator, float scale)
  11. throws IOException {
  12.     super(page);
  13.     this.page = page;
  14.     this.ofdCreator = ofdCreator;
  15.     ctLayer = this.ofdCreator.createLayer();
  16.     this.scale = scale;
  17. }
复制代码

  • 重写 drawImage 方法收集整理 PDF 中分析出来的图片资源
  1. /**
  2. 作用:将 PDF 图像对象转换为 OFD 格式进行绘制。此方法包括:
  3. *
  4. 将图像写入字节流并保存。
  5. 根据当前变换矩阵计算图像在页面上的位置和大小。
  6. 创建 OFD 图像对象并设置其相关属性,然后添加到当前层中。
  7. *
  8. @param pdImage
  9. @throws IOException
  10. */
  11. @Override
  12. public void drawImage(PDImage pdImage) throws IOException {
  13.     ByteArrayOutputStream bosImage = new ByteArrayOutputStream();
  14.     String suffix = "png";
  15.     ImageIO.write(pdImage.getImage(), suffix, bosImage);
  16.     String name = String.format("%s.%s", bcMD5(bosImage.toByteArray()), suffix);
  17.     ofdCreator.putImage(name, bosImage.toByteArray(), suffix);
  18.     // 根据当前变换矩阵计算图像在页面上的位置和大小,实际上就是将PDF中该图像的属性信息转换成OFD中的形式
  19.     Matrix ctmNew = this.getGraphicsState().getCurrentTransformationMatrix();
  20.     float imageXScale = ctmNew.getScalingFactorX();
  21.     float imageYScale = ctmNew.getScalingFactorY();
  22.     double x = ctmNew.getTranslateX() * scale;
  23.     double y = (page.getCropBox().getHeight() - ctmNew.getTranslateY() - imageYScale) * scale;
  24.     double w = imageXScale * scale;
  25.     double h = imageYScale * scale;
  26.     ImageObject imageObject = new ImageObject(ofdCreator.getNextRid());
  27.     imageObject.setBoundary(x, y, w, h);
  28.     imageObject.setResourceID(new ST_RefID(ST_ID.getInstance(ofdCreator.getImageMap().get(name))));
  29.     imageObject.setCTM(ST_Array.getInstance(String.format("%.0f 0 0 %.0f 0 0", w, h)));
  30.     setImageClip(imageObject, x, y, w, h);
  31.     ctLayer.add(imageObject);
  32. }
复制代码

  • 通过继承 PDFGraphicsStreamEngine 类分析得到的文字内容重绘
  1. public void addPageContent(int idx, CT_Layer ctLayer, float width, float height) {
  2.     PageDir pageDirInv = new PageDir();// 资源归类
  3.     pageDirInv.setIndex(idx);
  4.     org.ofdrw.core.basicStructure.pageObj.Page pageInv = new org.ofdrw.core.basicStructure.pageObj.Page();
  5.     CT_PageArea areaInv = new CT_PageArea();// ofd可视区域(PDF的裁剪区)
  6.     areaInv.setPhysicalBox(0, 0, width, height);
  7.     pageInv.setArea(areaInv);
  8.     Content contentInv = new Content();// 内容
  9.     contentInv.addLayer(ctLayer);
  10.     pageInv.setContent(contentInv);
  11.     pageDirInv.setContent(pageInv);
  12.     docDir.getPages().add(pageDirInv);
  13. }
复制代码

  • 将收集到的资源进行打包生成 OFD 文件
  1. /**
  2. 打包OFD文件包二进制数据
  3. *
  4. @param virtualFileMap
  5. @return
  6. @throws IOException
  7. */
  8. public static void zip(Map<String, byte[]> virtualFileMap,OutputStream output) throws IOException {
  9.     ZipArchiveOutputStream zaos = new ZipArchiveOutputStream(output);
  10.     for (Map.Entry<String, byte[]> entry : virtualFileMap.entrySet()) {
  11.         zaos.putArchiveEntry(new ZipArchiveEntry(entry.getKey()));
  12.         zaos.write(entry.getValue());
  13.         zaos.closeArchiveEntry();
  14.     }
  15.     zaos.finish();
  16. }
复制代码
最终效果展示:

完整代码的链接:
GcExcelTestArea.rar
总结
在当今时代,对于国产化的支持,OFD(Office Open XML for Developers)变得越来越告急。本文首先先容了OFD 文件的底层结构,并阐述了 OFD 相对于 PDF 的上风。接着,先容如何通过葡萄城的嵌入式 BI 工具——Wyn 贸易智能,进行报表计划和导出 PDF 。同时,还展示了如何使用 Wyn 贸易智能的 API 接口将 PDF 转换为 OFD,除此之外,在企业级复杂体系中,除了 OFD 之外,Wyn还同时支持Word、Excel、图片、Text、JSON等多种格式的导出。
通过本文的先容,我们可以清楚地看到,将 PDF 转换为 OFD 不再是一个困扰。借助 Wyn 强盛的功能和丰富的 API 接口支持,能够轻松高效地实现文档格式转换。这一办理方案为用户提供了便捷、灵活的操纵方式,满足了行业对 OFD 格式的要求。
扩展链接:
创意展示:打造数据大屏的炫酷天气预报插件
  聊一聊数字孪生与3D可视化
探秘移动端BI:发展历程与应用前景解析

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

罪恶克星

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表