从PDF到OFD,国产化浪潮下多种文档格式导出的完美解决方案

pdf,ofd · 浏览次数 : 20

小编点评

随着中国信息技术领域的自主创新和供应链安全意识的不断提高,OFD格式逐渐成为政府部门、金融、税务、教育、医疗等行业文件导出的首选标准。相较于PDF,OFD格式在开放性、功能特性、文件大小和兼容性等方面展现出明显优势。 OFD格式的开放性意味着任何人或组织都可以自由使用和开发相关软件,而不用担心受到Adobe公司的限制。功能特性方面,OFD格式在文档展示、打印、编辑等方面都有更强大的支持。此外,OFD格式的文件大小相对较小,有助于节省存储空间。在兼容性方面,OFD格式具有更好的跨平台一致性,可以在不同的软件和系统中无缝对接。 要将PDF转换为OFD格式,可以使用葡萄城的嵌入式BI工具——Wyn商业智能。Wyn提供了丰富的API接口,支持前端导出PDF文件,并实现了从PDF到OFD的一键转换。通过Wyn,用户可以轻松设计出符合需求的报表样式,并将报表导出为OFD格式,满足行业对OFD格式的要求。 总之,OFD格式凭借其开放性、功能特性、文件大小和兼容性等方面的优势,正逐渐成为中国信息技术领域文件导出的主流标准。借助Wyn商业智能的强大功能和丰富API接口支持,实现文档格式转换变得轻而易举,为用户提供了便捷、灵活的操作方式。

正文

前言

近年来,中国在信息技术领域持续追求自主创新和供应链安全,伴随信创上升为国家战略,一些行业也开始明确要求文件导出的格式必须为 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 文件主要由以下几个部分组成:

  1. 文档头(Document Header):包含文档的基本信息,如标题、作者、创建日期等。
  2. 文档体(Document Body):包含文档的实际内容,如文字、图片、表格等。
  3. 资源文件(Resource Files):包括文档中使用到的图片、字体、样式等资源。
  4. 元数据(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文件解析的方法

  1. 继承 PDFGraphicsStreamEngine 类,便于分析 PDF 数据图层和资源归类
public class OFDPageDrawer extends PDFGraphicsStreamEngine {

}
  1. 重写构造方法,分析 PDF 每页的资源,并初始化 OFD 生成器
/**
构造器,调用super(page),这个操作的目的是将page资源准备好,并且添加对应的操作符,
当下一次调用processPage或者processPageContentStream时执行对应的操作符对应的操作
@param idx
@param page
@param ofdCreator
@param scale
@throws IOException
*/
protected OFDPageDrawer(int idx, PDPage page, OFDCreator ofdCreator, float scale) 
throws IOException {
    super(page);
    this.page = page;
    this.ofdCreator = ofdCreator;
    ctLayer = this.ofdCreator.createLayer();
    this.scale = scale;
}
  1. 重写 drawImage 方法收集整理 PDF 中分析出来的图片资源
/**
作用:将 PDF 图像对象转换为 OFD 格式进行绘制。此方法包括:
*
将图像写入字节流并保存。
根据当前变换矩阵计算图像在页面上的位置和大小。
创建 OFD 图像对象并设置其相关属性,然后添加到当前层中。
*
@param pdImage
@throws IOException
*/
@Override
public void drawImage(PDImage pdImage) throws IOException {
    ByteArrayOutputStream bosImage = new ByteArrayOutputStream();
    String suffix = "png";
    ImageIO.write(pdImage.getImage(), suffix, bosImage);
    String name = String.format("%s.%s", bcMD5(bosImage.toByteArray()), suffix);
    ofdCreator.putImage(name, bosImage.toByteArray(), suffix);

    // 根据当前变换矩阵计算图像在页面上的位置和大小,实际上就是将PDF中该图像的属性信息转换成OFD中的形式
    Matrix ctmNew = this.getGraphicsState().getCurrentTransformationMatrix();
    float imageXScale = ctmNew.getScalingFactorX();
    float imageYScale = ctmNew.getScalingFactorY();
    double x = ctmNew.getTranslateX() * scale;
    double y = (page.getCropBox().getHeight() - ctmNew.getTranslateY() - imageYScale) * scale;
    double w = imageXScale * scale;
    double h = imageYScale * scale;
    ImageObject imageObject = new ImageObject(ofdCreator.getNextRid());
    imageObject.setBoundary(x, y, w, h);
    imageObject.setResourceID(new ST_RefID(ST_ID.getInstance(ofdCreator.getImageMap().get(name))));
    imageObject.setCTM(ST_Array.getInstance(String.format("%.0f 0 0 %.0f 0 0", w, h)));
    setImageClip(imageObject, x, y, w, h);
    ctLayer.add(imageObject);
}
  1. 通过继承 PDFGraphicsStreamEngine 类分析得到的文字内容重绘
public void addPageContent(int idx, CT_Layer ctLayer, float width, float height) {
    PageDir pageDirInv = new PageDir();// 资源归类
    pageDirInv.setIndex(idx);
    org.ofdrw.core.basicStructure.pageObj.Page pageInv = new org.ofdrw.core.basicStructure.pageObj.Page();
    CT_PageArea areaInv = new CT_PageArea();// ofd可视区域(PDF的裁剪区)
    areaInv.setPhysicalBox(0, 0, width, height);
    pageInv.setArea(areaInv);
    Content contentInv = new Content();// 内容
    contentInv.addLayer(ctLayer);
    pageInv.setContent(contentInv);
    pageDirInv.setContent(pageInv);
    docDir.getPages().add(pageDirInv);
}
  1. 将收集到的资源进行打包生成 OFD 文件
/**
打包OFD文件包二进制数据
*
@param virtualFileMap
@return
@throws IOException
*/
public static void zip(Map<String, byte[]> virtualFileMap,OutputStream output) throws IOException {
    ZipArchiveOutputStream zaos = new ZipArchiveOutputStream(output);

    for (Map.Entry<String, byte[]> entry : virtualFileMap.entrySet()) {
        zaos.putArchiveEntry(new ZipArchiveEntry(entry.getKey()));
        zaos.write(entry.getValue());
        zaos.closeArchiveEntry();
    }

    zaos.finish();
}

最终效果展示:

完整代码的链接:

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:发展历程与应用前景解析

与从PDF到OFD,国产化浪潮下多种文档格式导出的完美解决方案相似的内容:

从PDF到OFD,国产化浪潮下多种文档格式导出的完美解决方案

前言 近年来,中国在信息技术领域持续追求自主创新和供应链安全,伴随信创上升为国家战略,一些行业也开始明确要求文件导出的格式必须为 OFD 格式。OFD 格式目前在政府、金融、税务、教育、医疗等需要文件开放、共享和长期保存的行业中广泛应用。这种趋势在未来几年内将进一步增强。 相较于 PDF,OFD 在

Chrome 103支持使用本地字体,纯前端导出PDF优化

在前端导出PDF,解决中文乱码一直是一个头疼的问题。要解决这个问题,需要将ttf等字体文件内容注册到页面PDF生成器中。但是之前网页是没有权限直接获取客户机器字体文件,这时就需要从服务器下载字体文件或者提示用户选择字体文件上传到页面。对于动辄数十兆(M)的中文字体文件,网络不好时并不是一个好的解决方

Python 提取PDF文本和图片

从PDF中提取内容能帮助我们获取文件中的信息,以便进行进一步的分析和处理。此外,在遇到类似项目时,提取出来的文本或图片也能再次利用。要在Python中通过代码提取PDF文件中的文本和图片,可以使用 Spire.PDF for Python 这个第三方库。具体操作方法查阅下文。 Python 提取PD

C# 设置PDF表单不可编辑、或提取PDF表单数据

PDF表单是PDF中的可编辑区域,允许用户填写指定信息。当表单填写完成后,有时候我们可能需要将其设置为不可编辑,以保护表单内容的完整性和可靠性。或者需要从PDF表单中提取数据以便后续处理或分析。 之前文章详细介绍过如何使用免费Spire.PDF库通过C# 创建、填写表单,本文将继续介绍该免费.NET

Python潮流周刊的优惠券和精美电子书(EPUB、PDF、Markdown)

Python潮流周刊从 2023.05.13 连载至今,本周即将发布第 60 期,这意味着我们又要达成一个小小的里程碑啦! 每周坚持做分享,周复一周,这对自己的精力和意志是一项不小的挑战。于是,为了让自己获得一些仪式感,我给自己定了一个较为合理的时间目标,就是每 30 期周刊作为一季。 划分出“每一

如何使用Java创建数据透视表并导出为PDF

摘要:本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 前言 数据透视分析是一种强大的工具,可以帮助我们从大量数据中提取有用信息并进行深入分析。而在Java开发中,可以借助PivotTable,通过数据透视分析揭示数据中的隐藏

推荐一个 C#写的 支持OCR的免费通用扫描仪软件

NAPS2是一个开源免费软件,体积只有6M不到,支持运行在 Windows, Mac 和 Linux操作系统中,默认就带有简体中文界面,官方默认就提供绿色版,所以解压即可使用,直接可以从官方网站下载:https://www.naps2.com/。NAPS2全名叫做Not Another PDF Sc

从DDPM到DDIM (一) 极大似然估计与证据下界

从DDPM到DDIM (一) 极大似然估计与证据下界 现在网络上关于DDPM和DDIM的讲解有很多,但无论什么样的讲解,都不如自己推到一遍来的痛快。笔者希望就这篇文章,从头到尾对扩散模型做一次完整的推导。本文的很多部分都参考了 Calvin Luo[1] 和 Stanley Chan[2] 写的经典

从Mybatis-Plus开始认识SerializedLambda

从Mybatis-Plus开始认识SerializedLambda 背景 对于使用过Mybatis-Plus的Java开发者来说,肯定对以下代码不陌生: @TableName("t_user") @Data public class User { private String id; private

从基础到高级应用,详解用Python实现容器化和微服务架构

本文分享自华为云社区《Python微服务与容器化实践详解【从基础到高级应用】》,作者: 柠檬味拥抱。 Python中的容器化和微服务架构实践 在现代软件开发中,容器化和微服务架构已经成为主流。容器化技术使得应用程序可以在任何环境中一致运行,而微服务架构通过将应用拆分成多个独立的服务,从而提升了系统的