采用WPF技術,開發OFD電子文檔閱讀器


前言 OFD是國家標准版式文檔格式,於2016年生效。OFD文檔國家標准參見《電子文件存儲與交換格式版式文檔》。既然是國家標准,OFD隨后肯定會首先在政務系統使用,並逐步推向社會各個方面。OFD是在研究當下各類文件格式后,推出的標准,有如下優點:

1 產權屬於自主產權

2 具有便攜性:文件小,可壓縮比率大。測試顯示生成的文件體量比PDF還要小。

3 具有開放性:易於入門,對於使用者來說更具開放性。

4 具有擴展性:預留了可擴展入口和自定義標引,設置了非接觸式引用機制,為特性化提供支持。

5 呈現效果與設備無關,在各種設備上閱讀、打印或印刷時,版面固定、不跑版。

6 應用廣泛:無論是電子商務、電子公務,還是信息發布、文件交換,檔案管理等都需要版式文檔的技術支持。

  關於標准,我也要吐槽一下。OFD標准是國內幾家專業的電子文檔處理公司參與起草的;標准文檔(注:以下用”標准”特指OFD標准)只有126頁,在我看來,標准對技術細節的描述過於簡單,沒有一定的技術背景很難看懂。與此形成鮮明對比的是pdf標准,有1000多頁。我在網上也沒找到文字版的標准,特別不利於閱讀和參考。

ofd閱讀器程序(已集成了轉圖、轉PDF功能)下載。

  我最近一直研究ofd標准,試圖寫一款閱讀器,已初有成果。具有ofd轉換為pdf、轉為圖片等特色功能。界面如下:

 

 

 

 

 本文就把我開發的過程做簡單介紹。

OFD標准簡介

  簡而言之,OFD存儲是采用壓縮技術,描述采用XML格式。這一點與微軟的word文檔(docx)格式很類似。標准可能參考了微軟的處理方式;在技術上也要實事求是,國標這種格式不是獨創和領先的。將OFD格式文件解壓后,會看到如下目錄和文件:

 

文件中會包括資源文件(圖片、字體庫等)。XML會對資源存放,圖元(文字、圖像等)顯示做描述,閱讀軟件會根據這些描述呈現出一致的顯示效果。

 

開發OFD閱讀軟件步驟

  國內流行的ofd閱讀軟件應該是福昕和數科開發的,這兩款我都用過。我還要吐槽一下:

  1)福昕閱讀器幫助文檔是ofd格式,但是無法用數科的閱讀器打開。

  2)有些ofd文檔中xml標記,在標准中找不到,是某些公司獨創的?

  這些軟件都是用C++開發的,用到了QT。同樣情況下,相比於C#,C++開發軟件難度肯定會大增。在windows平台開發界面,WPF應該是最好的庫了。WPF雖然出現十幾年了,大家好像對此還很陌生。主要現在是BS的天下;不是WPF不夠好,是生不逢時。

1 對OFD文件解壓縮

  OFD文件其實就是壓縮文件,解壓后的文件也有目錄結構。該模塊的功能是獲取每個文件的路徑和數據。

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;

namespace WpfOfdReader.OfdFileType
{
    class OfdFileReader
    {
        ZipArchive _zipArchive;
        public void ReadZipFile(string fileName)
        {
            _zipArchive = ZipFile.OpenRead(fileName);
        }

        public void Close()
        {
            if (_zipArchive != null)
                _zipArchive.Dispose();
        }

        public List<OfdFileItemInfo> AllFileItem
        {
            get
            {
                return _zipArchive.Entries.Select(o => new OfdFileItemInfo(o)).ToList();
            }
        }

        private ZipArchiveEntry GetArchiveEntry(ZipFilePath path)
        {
            foreach (ZipArchiveEntry entry in _zipArchive.Entries)
            {
                if (entry.FullName == path.FulleName)
                {
                    return entry;
                }
            }
            return null;
        }

        public static byte[] GetFileBuffer(ZipArchiveEntry entry)
        {
            List<byte[]> listBuffer = new List<byte[]>();
            using (Stream s = entry.Open())
            {
                while (true)
                {
                    byte[] buffer = new byte[10];
                    int n = s.Read(buffer, 0, buffer.Length);
                    if (n <= 0)
                        break;

                    if (n == buffer.Length)
                    {
                        listBuffer.Add(buffer);
                    }
                    else
                    {
                        Array.Resize(ref buffer, n);
                        listBuffer.Add(buffer);
                        break;
                    }
                }
            }

            int totalLen = 0;
            listBuffer.ForEach(o => totalLen += o.Length);
            byte[] result = new byte[totalLen];
            int index = 0;
            foreach (byte[] buffer in listBuffer)
            {
                Buffer.BlockCopy(buffer, 0, result, index, buffer.Length);
                index += buffer.Length;
            }
            return result;
        }
    }
}

 2 找到需要展示的page

  順着路線 OFD.xml --> Document.xml --> Pages,找到最終需要展示的page頁。Page頁包含三類節點:PathObject、ImageObject,暨對應標准中的三類圖元。需要對這三類節點建模。這三個類共同繼承父類PageObject。所有的圖元都有繪制區域、坐標變換、裁剪等共性,所有這些由PageObject類處理。

 

 3 創建WPF顯示模型

圖像精確定位需要用到Canvas控件作為容器。繪制大量圖形需要用到輕量級繪制模型DrawingVisual。在此基礎上,派生了繪制基礎模型OfdVisual,此模型對應PageObject。 

 

有三種類型繪制對象OfdVisualText、OfdVisualPath、OfdVisualImage,派生自OfdVisual。分別處理三種圖元數據。所有的繪制操作在函數

public override void Show(bool visiable, bool even = false);

對應文本,繪制函數如下:

 

 繪制前,需要對當前坐標做變換、旋轉、剪切等操作。

最近又對程序完善了,增加縮略圖和公文索引:

 

 

 

 

后記 編寫閱讀器類軟件的關鍵是建模。首先讀懂標准,對標准中描述的圖元做歸類分析,並建立起相應的顯示模型。本人做WPF開發很多年了,感覺用WPF開發這類軟件並不是非常的難。相比於QT,采用wpf開發有很多優勢。如果要完整實現OFD標准,還需要大量的開發,我會逐步完善該軟件的功能。

特別說明

ofd閱讀器開發語言為c#,具有完全自主產權,沒有使用第三方ofd開發包。可以根據你的需求快速定制開發。本閱讀器還在開發完善階段,如有任何問題,可以聯系我QQ:13712486。博客:https://www.cnblogs.com/yuanchenhui/ 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM