What is OFD
OFD (Open Fixed-Layout Documents) Is an electronic document with a highly accurate and Fixed layout effect, and its presentation is independent of devices.
Similar to PDF files, it has the characteristics of independent format, fixed layout and solidified presentation. It can be said that OFD is the Chinese version of PDF, but its performance is better than that of its counterpart in many aspects. OFD has gradually begun to be used in the fields of electronic invoices, electronic documents, electronic certificates and so on.
The country is promoting OFD format for office documents.
In short, OFD is customized by our country, while PDF is made by American company.
At present, OFD is mainly used in government agencies, which cannot directly open files and requires professional OFD readers.
Ofd. js to realize the ofD file preview function
Ofd.js is an open source project JavaScript toolkit on Gitee. Here, I would like to thank the author.
The author’s Gitee address is as follows:
Gitee.com/Donal/ofd.j…
The installation
npm i ofd.js
Copy the code
The introduction of
import {parseOfdDocument, renderOfd} from "ofd.js";
Copy the code
The core code
// The ofd file can be a local file, binary file or URL. ScreenWidth can be the width of the screen
parseOfdDocument({
ofd: file,
success(res) {
// Output div of ofd per page
const divs = renderOfd(screenWidth, res);
// Obtain information about the signature div. See demo for details
for(let ele of document.getElementsByName('seal_img_div')) {
this.addEventOnSealDiv(ele, JSON.parse(ele.dataset.sesSignature), JSON.parse(ele.dataset.signedInfo)); }},fail(error) {
console.log(error)
}
});
Copy the code
OFD Component code
<template>
<a-modal :title="title" :visible="visible" @cancel="handleCancel" width="70%" :footer="null">
<a-spin :spinning="loading" tip="Loading">
<div class="page-box">
<div class="option-list" v-if="ofdObj">
<div class="scale-icon" style="margin-left: 10px" @click="plus">
<! - zoom - >
<a-icon type="plus-circle" />
</div>
<div class="scale-icon" @click="minus">
<! Narrow -- -- -- >
<a-icon type="minus-circle" />
</div>
<div class="scale-icon">
<! -- Page 1 -->
<a-icon type="step-backward" @click="firstPage" />
</div>
<div class="scale-icon" @click="prePage">
<! -- Previous page -->
<a-icon type="caret-left" />
</div>
<div class="scale-icon">
<! -- Current page number and total page number -->
{{ pageIndex }}/{{ pageCount }}
</div>
<div class="scale-icon" @click="nextPage">
<! -- Next page -->
<a-icon type="caret-right" />
</div>
<div class="scale-icon" @click="lastPage">
<! -- Last page -->
<a-icon type="step-forward" />
</div>
</div>
</div>
<div class="modal-box" id="ofd-preview-box">
<! -- File area -->
<div class="main-section" :class="{ 'background-shadow': loadOverFlag }" id="content" ref="contentDiv"></div>
</div>
</a-spin>
</a-modal>
</template>
<script>
import { parseOfdDocument, renderOfd, renderOfdByScale, getPageScale, setPageScale } from 'ofd.js'
export default {
name: 'OfdPreview'.components: {},
props: {
title: {
type: String.default: 'OFD File Preview ',},fileUrl: {
type: String.default: ' ',}},data() {
return {
ofdObj: null.pageIndex: 1.pageCount: 0.scale: 0.loading: false.visible: false.loadOverFlag: false.screenWidth: 1000,}},watch: {},
computed: {},
methods: {
showModal() {
this.visible = true
this.$nextTick(() = > {
this.screenWidth = document.getElementById('ofd-preview-box').getBoundingClientRect().width - 30
this.getOfdDocumentObj(this.fileUrl, this.screenWidth)
})
},
handleCancel(e) {
this.visible = false
},
getOfdDocumentObj(file, screenWidth) {
let that = this
this.loading = true
parseOfdDocument({
ofd: file,
success(res) {
that.ofdObj = res[0]
that.pageCount = res[0].pages.length
const divs = renderOfd(screenWidth, res[0])
that.displayOfdDiv(divs)
that.loadOverFlag = true
that.loading = false
},
fail(error) {
that.loading = false
console.log('OFD failed to open ')}})},displayOfdDiv(divs) {
this.scale = getPageScale()
let contentDiv = document.getElementById('content')
contentDiv.innerHTML = ' '
for (const div of divs) {
contentDiv.appendChild(div)
}
},
plus() {
setPageScale(++this.scale)
const divs = renderOfdByScale(this.ofdObj)
this.displayOfdDiv(divs)
},
minus() {
setPageScale(--this.scale)
const divs = renderOfdByScale(this.ofdObj)
this.displayOfdDiv(divs)
},
prePage() {
let contentDiv = document.getElementById('content')
let ele = contentDiv.children.item(this.pageIndex - 2)
if (ele) {
ele.scrollIntoView(true)
this.pageIndex = this.pageIndex - 1}},firstPage() {
let contentDiv = document.getElementById('content')
let ele = contentDiv.firstElementChild
if (ele) {
ele.scrollIntoView(true)
this.pageIndex = 1}},nextPage() {
let contentDiv = document.getElementById('content')
let ele = contentDiv.children.item(this.pageIndex)
if (ele) {
ele.scrollIntoView(true) + +this.pageIndex
}
},
lastPage() {
let contentDiv = document.getElementById('content')
let ele = contentDiv.lastElementChild
if (ele) {
ele.scrollIntoView(true)
this.pageIndex = contentDiv.childElementCount
}
},
},
created() {},
mounted(){},}</script>
<style lang="scss" scoped>
.wrapper{}.modal-box {
width: 100%;
height: 55vh;
overflow: auto;
}
.main-section {
width: 100%;
padding-top: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
position: relative;
}
.background-shadow {
background: # 808080;
}
.page-box {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
margin-bottom: 15px;
.option-list {
display: flex;
align-items: center;
justify-content: center;
width: 100%; }}.scale-icon {
display: flex;
cursor: pointer;
justify-content: center;
align-items: center;
width: 33px;
height: 28px;
border-radius: 1px;
font-weight: 500;
font-size: 18px;
color: # 333333;
text-align: center;
padding: 2px;
}
.scale-icon :hover {
color: #1890ff;
}
.ant-spin-nested-loading > div > .ant-spin {
max-height: auto ! important;
}
</style>
Copy the code