為什麼 PDF 能保證排版一致性,但通常 Word 文檔不能做到?

因為每次用 WPS 寫的 Word 到了 MS Office 上似乎排版都不能保證一致,所以來問問原因。但是 PDF 似乎可以保證,甚至連字體缺失的時候都能保證,這是為什麼?


以前和WPS的章總(章慶元)聊過WPS的一些事情。單就doc格式([MS-DOC]: Word (.doc) Binary File Format)而言,WPS和Word在讀取的操作上就有一定的差異。這還是底層上的差異,而就上層的差異來講,這很明顯受制於WPS的各位架構師對於排版本身的理解。這種理解,有排版技術上的,還有對於技術外的平衡(尤其是性能)。當然還有經濟因素,很明顯,WPS在代碼量級以及開發成本上是不能和Word做一個比較的,體量上相差太多。所以就算是保存成一個doc文件,在兩個軟體平台上自然是不能夠保證一樣的。

而PDF為什麼大部分情況下能夠基本保證一樣呢?這是因為,WPS/Word所讀取的是文檔,在文件格式本身內是不規定最終效果應該是什麼樣的,最終的效果完全取決於軟體本身。PDF格式在設計上是直接面向於頁面的,甚至可以說,這種格式天生是面向印表機設計的(事實也是如此)。PDF在設計上,也比doc/docx簡單很多,甚至可以理解為PDF是個矢量圖形格式。


PDF就像一幅畫,保證了排版的一致性,但是沒有保留文檔的邏輯結構,沒法編輯。所以docx和pdf各司其職,題主為什麼不試一下在word那裡另存為pdf再給別人呢?需要注意的是,從實用性來講,docx轉pdf是單向的,轉回來的都是屎。

不過話說回來,MS Office沒有義務保證WPS輸出的Word文檔的任何問題,那是金山公司要解決的。


PDF 是矢量圖

DOC(X) 是帶結構文檔


PDF:距離頂端3厘米有兩個字距離左端5厘米,字體在這,拿去用。距離頂端5厘米,距離左端5厘米還有兩個字。

doc:文檔里有兩個字,字體是中易宋體,沒有的話serif就行,行高1.5倍,自己去字體里找。然後有一個換行符,然後又有兩個字。

修改PDF:把每一行的最後一個字都挪到下一行去,檢查一下標點的問題……

修改doc:在這個位置加一個字。


1、市面上的PDF文檔至少有一半純粹就是一頁一張圖片,這根本就不能稱之為文檔,只能叫做相簿。而剩下的文檔裡面,PDF儲存的也不是文檔內容,而是各個符號圖片所在頁面的位置,或者你就認為PDF文檔事實上就是一個多圖層的圖片文檔就對了,像PSD那樣,這當然不會失真。一篇文章在抄來抄去的過程中會失真,但是一副剪貼畫怎麼失真?

2、Word也可以把文檔保存為XPS格式的文檔,這個格式可以保證一定不會失真,但是,你也基本沒法編輯了……


PDF保證格式的前提是犧牲了可編輯性。

你可以這麼理解:Word文檔之所以不能保證打開後排版一致,是因為Word文檔保存的並不是你文檔格式的實際內容,而是保存了它們所對應的代碼。不同版本的軟體在還原這些代碼時可能有偏差,這就導致了實際顯示效果的差異。其好處是可編輯性強,而且能夠顯著縮小文檔體積。

而PDF文檔則可以理解成是直接將文檔中的內容保存為圖形。其中能保存為矢量的圖形則保存為矢量圖形,不能的則保存為點陣圖形。保存為圖形以後,格式就不容易發生變化了,不過很多東西也就難以重新編輯了,而且文檔大小也會顯著增大。

所以,在實際應用中,具體選擇哪個還是要看個人需求。如果對Word文檔的保真性有很強的要求,那麼請做到以下幾點:

一、盡量不要使用WPS創建Word文檔,而是使用微軟Office,畢竟微軟才是doc和docx格式的定義者;

二、在所有電腦上使用微軟Office的最新版本,同時也要推薦同事使用,這樣才能最大程度保證文件在所有電腦上的打開效果都是一致的。有能力的話推薦使用Office 365訂閱,不想花這個錢也要盡量安裝最新版Office。順便說一下,現在手機和平板電腦上也可以安裝微軟Office,是獨立的Word、Excel和PowerPoint應用,如果有需要也可以嘗試;

三、如果沒有特殊需要,盡量使用docx格式保存文檔,而不要使用古老的doc格式。docx對文檔格式保真度的提升是有目共睹的,現在使用docx格式的文檔已經很少出現排版問題了,題主可以嘗試一下。


PDF是板式文檔, 發明出來就是為了保證列印效果一致.

另外PDF是可以編輯的. 不僅能夠編輯還可以手寫.


下面是手寫的PDF 保存成xx.pdf就可以打開了.

%PDF-1.7 % The file header, indicating this is a PDF file

% The main part of the PDF file: all indirect objects

1 0 obj % the root node of page tree
&<&< /Type /Pages /Kids [2 0 R 2 0 R 2 0 R] % kids under this node. % Can be another page tree node, or a page dictionary /Count 3 &>&>
endobj

2 0 obj % a page dictionary
&<&< /Type /Page /Parent 1 0 R % parent page tree node /MediaBox [0 0 612 792] % page size (612x792 points) /Contents 4 0 R % content stream /Resources &<&< % resource dictionary /Font &<&< % font list /Font1 5 0 R &>&>
/XObject &<&< % XObject list (including forms and images) /Image1 6 0 R &>&>
&>&>
&>&>
endobj

3 0 obj % the catalog dictionary.
&<&< /Type /Catalog /Pages 1 0 R % pointer to the root node of pages tree &>&>
endobj

4 0 obj % the page content stream
&<&< /Length 0 % should be byte length of the stream data. % We use 0 here for convenience. &>&> stream

% Path example: show a red line across the page

1 0 0 RG % set to red color
0 792 m % move to left-top corner
612 0 l % line to right-bottom corner
s % stroke the path

% Text example: draw "Hello World!" text

BT % begin text object
/Font1 10 Tf % set font to /Font1, font size to 10 points
100 700 TD % move text position to 100,700
(Hello World!!!) Tj % output the text
ET % end text object

BT % begin text object
/Font1 10 Tf % set font to /Font1, font size to 10 points
100 100 TD % move text position to 100,700
(Hello World!!!) Tj % output the text
ET % end text object

% Image example: output a colored image

q % save graphic states (including current matrix)
100 0 0 100 300 600 cm % change the current matrix for the image
/Image1 Do % display the image
Q % restore graphic states (including current matrix)

endstream
endobj

5 0 obj % a font dictionary.
% This is a base-14 font, so only a few data is required.
&<&< /Type /Font /Subtype /Type1 /BaseFont /Helvetica &>&>
endobj

6 0 obj % a colored image
&<&< /Type /XObject /Subtype /Image /Width 8 % pixel width /Height 8 % pixel height /ColorSpace /DeviceRGB % color space: each pixel uses R,G,B components /BitsPerComponent 8 % each component uses one byte /Length 0 % should be length of image data. % Use 0 here for convinience /Filter /ASCIIHexDecode % use hexidecimal form for convinience &>&> stream
FF0000 C00000 A00000 800000 600000 400000 200000 0000FF
FF2000 C00000 A00000 800000 600000 400000 200000 0000C0
FF4000 C00000 A00000 800000 600000 400000 200000 0000A0
FF6000 C00000 A00000 800000 600000 400000 200000 000080
FF8000 C00000 A00000 800000 600000 400000 200000 000060
FFA000 C00000 A00000 800000 600000 400000 200000 000040
FFC000 C00000 A00000 800000 600000 400000 200000 000020
FFFF00 C0C000 A0A000 808000 606000 404000 202000 000000&>
endstream
endobj

xref % Cross reference table.
% Should contain byte offsets of all indirect objects
% We omit the cross reference table here for convenience.

trailer % The trailer part.
&<&< /Size 0 % should be the size of cross reference table % we use 0 here for convenience. /Root 3 0 R % pointer to the catalog object &>&>

startxref
0 % this should be the offset to the cross reference table.
% We use 0 here for convenience.
%%EOF % end of file
&


字體問題是因為pdf根本不需要讀取字體文件,直接以矢量圖存進去了

word也有辦法,比如我作為日系字體愛好者,寫文檔都是日系字體,所以我保存時都會勾上把字體嵌入文檔,增大20m體積換字體統一


這就和為什麼照片可以保留那麼真實的世界而顯卡卻很難渲染出來一個道理


PDF的本質是一個印表機腳本。而PDF的查看工具像一個虛擬印表機。PDF的編輯工具這麼難做,是因為要在面向輸出的格式上,重新規划出一個面向編輯的界面本身就很困難。PDF格式的設計,本質上就要求了在所有支持PS的印表機上(或列印驅動上)完美的精確的一致性復現。

WORD則是一個面向編輯的數據格式。它的設計是保存了一個編輯中的文檔。至於它怎麼被展示出來,那取決於展示它的工具以及運行工具的環境。WORD文件本身並沒有包含足夠多的一致性復現信息。


word和wps之間轉換有偏差, 估計應該只是因為有些專利或者技術壁壘導致的兼容問題.

本質都是流式結構,文本換行默認是根據容器邊界來自動完成的. 特點是中間插入東西, 會自動擠壓上下文去填充容器(文檔邊界).

但是PDF跟word之間就完全不是同一類東西了,PDF內的東西大部分都被轉為絕對定位的內容了,

文本完全切成行, 不存在換行了.

而且噁心的一些, 同一行的文本,會根據一個不知道原理的方式把一行文字切割成了很多個獨立定位的詞.

而且pdf對字體的存儲比較苛刻. 很多時候, 你看到的字其實已經不是字.


Word 的賣點是自動排版,隨便編輯。比如你打一句話,行末有逗號,你不用擔心逗號被擠出本行。別覺得這簡單,這些細節決定了你寫作時不用考慮太多。

PDF 的幾乎無法編輯,基本可以看成一張張圖片,需要的資源,比如缺少的字體 都已經打包在 PDF 里了。


你需要 markdown


PDF其實也不能保證排版一致性(只是在PS印表機下一致性基本可以得到保障)。目前能夠最好保證排版一致性的是JPEG,png等(點陣)圖片文件。


同意 @vczh

另外Word是微軟的私有格式,WPS不可能完全且完美地支持


推薦閱讀:

TAG:PDF | MicrosoftOffice | MicrosoftWord | 文檔 |