該文由小居工做室原創(QQ:2482052910)翻譯並提供解答支持,原文地址:Pdf File Writer 中文應用(PDF文件編寫器C#類庫):http://www.cnblogs.com/wjs5943283/p/6528853.htmlhtml
首先 Pdf File Writer 是一個很好用的PDF文件生成工具,因爲做者對中文編碼不熟悉,涉及到中文字體的輸出會發生異常,通過本人屢次測試,仿宋、黑體字體的中文還比較好,不容易發生異常。宋體測試不少次都沒有成功,包括諮詢了做者本人也沒有獲得滿意的答案:程序員
這一篇主要是對 PDF-File-Writer的使用進行中文翻譯,在各位使用的過程當中有什麼問題,能夠聯繫我。我已經在生產環境中使用。web
原文地址:https://www.codeproject.com/Articles/570682/PDF-File-Writer-Csharp-Class-Library-Version?msg=5362362#xx5362362xx編程
下面爲全文翻譯:數組
PDF文件編寫器C#類庫 瀏覽器
(版本1.19.1加強版)安全
- 下載PDF文件的示例 - 258 KB => 01
- 下載C#類庫(DLL) - 50.5 KB => 02
- 下載演示項目(包括DLL) - 546.5 KB => 03
- 下載源 - 860.4 KB => 04
已所有打包到百度雲盤:連接:http://pan.baidu.com/s/1nvFKDvj 密碼:apj0 網絡
示例生成的PDF文件:app
1.介紹
PDF文件編寫器C#類庫PdfFileWriter
容許您直接從.net應用程序建立PDF文件。庫免除了您的PDF文件結構的細節。要使用庫,您須要添加對附加PdfFileWriter.dll
的類庫文件的using PdfFileWriter
引用,在使用庫的每一個源文件中添加一個語句,幷包含PdfFileWriter.dll
與您的分發。有關更多詳細信息,請轉到2.23安裝。或者,您能夠在應用程序中包含庫的源代碼,並避免分發單獨的數據連接庫文件。最低開發要求是.NET Framework 4.0(Visual Studio 2013,在vs2012中使用也很正常)。框架
版本1.19.0修改說明
- 文檔連接容許PDF文檔用戶單擊連接並跳轉到文檔的另外一部分。添加文檔連接分爲兩部分。目標定義爲位置標記。位置標記必須具備惟一的名稱,範圍(
LocalDest
或NamedDest
)和位置(頁面和位置)。第二部分是連接位置。這兩個部分能夠按任何順序定義。他們被綁在一塊兒的名字。名稱區分大小寫。許多連接能夠指向同一位置標記。
- 命名目標是PDF文檔中的目標。它們使用位置標記以與文檔連接相同的方式定義。範圍必須設置爲NamedDest。當諸如Adobe Acrobat的PDF閱讀器打開PDF文檔時,它能夠在查看窗口中顯示目標時打開文檔。有關詳細信息,請參見第2.22節「 文檔連接」和「命名目標」。
PdfFileWriter
庫的如下功能已修改:Web連接,視頻顯示,音頻播放,保存或查看嵌入文件。在庫的之前版本中,Web連接由DrawText
方法TextBox
和PdfTable
類支持。從1.19.0開始,相同的支持可用於記錄連接,視頻,音頻和嵌入文件。
- 對於代碼示例,請查看OtherExample.ca和OtherExample.pdf。特別注意目錄頁和頁碼7。
- 版本1.19.1 Fix:AddLocationMarker修復具備小數分隔符而不是句點的區域。
從1.18.0 / 1.19.0以前的PdfFileWriter庫升級
字體資源建立修改自:
// 原建立字體方式:
FontResource = new PdfFont(Document, FontName, FontStyle, EmbeddedFont);
// 新的建立方式:
FontResource = PdfFont.CreatePdfFont(Document, FontName, FontStyle, EmbeddedFont);
換句話說,一個全局性的「查找和替換」從new PdfFont
到PdfFont.CreatePdfFont
會作的工做。
已命名目標已修改:
// 原
Document.AddNamedDestination(DestName, Page, FitArg, SideArg);
// 現
Page.AddLocationMarker(LocMarkerName, Scope, FitArg, SideArg);
PDF文件編寫器C#類庫支持如下PDF文檔的功能:
圖形:繪製線條,矩形,多邊形,貝塞爾曲線,前景和背景顏色,圖案和陰影。第2.1節座標系。
圖像:繪圖光柵(位圖)圖像和矢量(圖元文件)圖像。第2.4節。圖像支持。
文本:在列中繪製文本行和文本。第2.3節語言支持。
條形碼:支持條形碼128,條形碼39,條形碼交錯2,條形碼EAN13和條形碼UPC-A。第2.5節條碼支持。
QR碼:支持二維碼。第2.8節QR碼支持。
加密:支持AES-128加密。第2.6節加密支持。
Web連接:Web連接交互支持。第2.7節Web連接支持。
書籤:支持文檔大綱。第2.9節書籤支持。
命名目標:支持使Acrobat在特定頁面打開PDF文檔。第2.22節文檔連接和命名目的地。
圖表:支持Microsoft Charting。第2.10圖表支持。
打印到PDF:從PrintDocument過程建立PDF文檔。2.11節PrintDocument支持。
顯示數據表。第2.12節數據表支持
播放視頻文件。2.13節播放視頻文件
播放聲音文件。2.14節播放聲音文件
附加數據文件。第2.15節附加數據文件
從新排序頁面。第2.16節從新排序頁面
PDF文檔輸出到文件或流。第2.17節PDF文檔輸出。
PDF文檔信息字典。PDF閱讀器在文檔屬性的「說明」選項卡中顯示此信息。信息包括:標題,做者,主題,關鍵字,建立的日期和時間,修改的日期和時間,生成文件的應用程序,PDF生成器。第2.18節文檔信息字典。
內存控制:將已完成頁面的內容信息寫入輸出文件,並使用垃圾回收器釋放未使用的內存。第2.19節。內存控制。
繪製由System.Windows.Media.PathGeometry類定義的圖形。輸入參數能夠是文本字符串或PathGeometry類。第2.20節Windows Presentation Foundation WPF
透明度或不透明度如今可用於繪製形狀,線條,文本和圖像。您的應用程序能夠爲全部圖形和文本設置顏色的Alpha組件。第2.21節透明度,不透明度,Alpha顏色份量和混合
混合。新庫支持PDF顏色混合方案。混合定義如何處理在先前項目上繪製的新項目的顏色。第2.21節透明度,不透明度,Alpha顏色份量和混合
建立PDF是一個六個步驟的過程。
步驟1:建立一個文檔對象PdfDocument。
步驟2:建立資源對象,如字體或圖像(ie PdfFont 或PdfImage)。
步驟3:建立頁面對象PdfPage。
步驟4:建立內容對象PdfContents。
步驟5:向內容對象添加文本和圖形(使用PdfContents方法)。
對其餘頁面重複步驟3,4和5
步驟6:經過調用CreateFile方法建立您的PDF文檔文件PdfDocument。
步驟5是您的大部分編程工做將花費的地方。經過調用PdfContents類的方法來渲染圖形和文原本實現添加內容。內容類具備豐富的集(大約100種)用於向文檔中添加文本和圖形的方法。
PdfDocument實現IDisposable接口釋放非託管資源。建立PDF文件後CreateFile調用該方法Document.Dispose()。然而,爲了確保資源的釋放,你應該用一個語句或一個block./p> 包裝PdfDocument建立和最終CreateFileusingtry/catch
本文附帶的演示程序是開發用於調試庫的測試程序。在TestPdfFileWriter有主屏幕上的六個按鈕。五個按鈕生成PDF文件的示例,一個按鈕顯示計算機上可用的全部字體。第一個按鈕「文章示例」建立顯示在本文頂部的PDF文件。第3節。
如前所述,PdfFileWriterC#類庫使您免受PDF文件結構的複雜性。然而,良好的瞭解PDF文件老是一個優點。Adobe PDF文件規範文檔可從Adobe網站得到:「PDF參考,第六版,Adobe便攜式文檔格式版本1.7,2006年11月」。這是一個使人恐懼的1310頁的文件。我強烈建議閱讀第4章圖形以及文本第5章的第5.2和5.3節。
若是你想分析這個項目建立的PDF文件,或者若是你想了解通常的PDF文件結構,你可使用個人上一篇文章「PDF文件分析器與C#解析類」附帶的演示程序。本文簡要介紹了PDF規範。
2. PDF文件編寫器庫通常說明
2.1 座標系和測量單位
PDF座標系原點在頁面的左下角。X軸指向右邊。Y軸指向向上的方向。
PDF計量單位是點。一英寸有72點。PDF文件編輯器容許您選擇本身的計量單位。表示位置,寬度或高度的全部方法參數必須在您的度量單位中。有兩個例外:字體大小和分辨率。字體大小始終爲點。分辨率始終爲每英寸像素數。PDF文件編寫器將全部輸入參數轉換爲點。全部內部測量值和計算均採用雙精度。在建立PDF文件的最後一步,將值轉換爲文本字符串。轉換精度爲六位數。使用的轉換公式爲:
// Double類型
if(Math.Abs(Value) < 0.0001) Value = 0.0;
String Result = ((Single) Value).ToString();
2.2 小數分隔符
諸如Adobe Acrobat之類的PDF閱讀器指望實數具備小數,以使用句點做爲小數分隔符。一些世界地區使用其餘小數分隔符,如逗號。因爲PDF File Writer庫的版本1.1將使用句點做爲小數分隔符,而不考慮計算機的區域設置。
2.3 語言支持,字體和字符集
PDF文件編寫器庫支持您計算機上安裝的大多數字體。惟一的例外是設備字體。支持的字體遵循OpenType字體規範。有關詳細信息,請參閱Microsoft字體 - OpenType規範。要繪製的文本存儲在由Unicode字符組成的字符串中。該庫將接受除控制代碼0到31和128到159以外的任何字符(0到65536)。每一個字符都將轉換爲字形。字形在頁面上從左到右以與存儲在字符串中的順序相同的順序繪製。實際上,全部字體文件只支持全部可能的Unicode字符的一個子集。換句話說,您必須選擇支持項目語言的字體或要嘗試顯示的符號。若是輸入字符串包含不受支持的字形,PDF閱讀器將顯示「未定義字形」。一般它是一個小矩形。本文附帶的測試程序有一個「字體族」按鈕。若是單擊它,您能夠在計算機上查看全部可用的字體,並在每一個字體中查看全部可用字符。若是項目的語言是從左到右的語言,每一個字符被翻譯成一個字形,而且字形在字體中定義,結果應該是你指望的。若是結果不是您指望的結果,如下是一些額外的註釋:
Unicode控制字符。Unicode控制字符用於控制文本的解釋或顯示,但這些字符自己沒有視覺或空間表示。PDF文件編寫器不識別這些字符。庫假定每一個字符都是顯示字符。它們將顯示爲未定義字符。
從右到左語言。一般,文本字符串中的字符的順序是人們讀取它們的順序。因爲庫從左到右繪製,文本將被向後寫。該ReverseString
方法顛倒字符順序。若是文本只有從右到左的字符,這將解決問題。若是文本是從右到左,從左到右,數字和一些字符如括號()[] <> {混合,它不會產生所需的結果。另外一個限制是TextBox
類不能打斷長到右文本到行。
在某些語言中,兩個或多個字符的序列被組合在一塊兒以顯示一個字形。您的軟件能夠識別這些序列並將其替換爲正確的字形。
虛線圓。若是你看看Glyph Metrics屏幕的Glyph列,你能夠看到一些glyphs有一個小的虛線圓圈(即字符代碼2364和2367)。這些字符是字符序列的一部分。不顯示虛線圓圈。若是前進寬度爲零,邊界框在Y軸的左側,則此字形將爲drawen ok。它將顯示在上一個字符的頂部。若是前進寬度不爲零,則此字形應顯示在上一個字符以前。你的軟件能夠經過顛倒這兩個字符來實現。
2.4 圖像支持
在PDF文檔中顯示圖像由PdfImage類和PdfImageControl類處理。圖像源能夠是圖像文件或.NET Image派生類或用於黑白圖像的布爾數組。圖像以Jpeg格式保存到PDF文件,索引位圖,灰色位圖或黑白位圖。位圖格式是無損壓縮。PdfImageControl控制保存圖像的過程。彩色圖片應以Jpeg格式保存。要控制圖像數據大小,您能夠下降分辨率或更改圖像質量。彩色圖像能夠以灰色陰影保存。數據大小減小了三個,但你失去了顏色。若是圖像是以圖表中的編程方式建立的,而且顏色數小於256,則圖像能夠保存爲索引位圖。每一個顏色由與3個字節相比的一個字節(或更少)表示。這能夠致使很是重要的文件大小減小。ChartExample.pdf文件從642KB減小到72KB。若是圖像是黑白的,如在PdfPrintDocument圖像的文本,圖像能夠保存爲BWImage。在PrintExample.pdf的狀況下,Jpeg文件是1795KB,黑白版本是66KB。
dfFileWriter庫中的其餘三個類使用PdfImage支持。類是:PdfChart,PdfQRCode和PdfPrintDocument。
圖片是PDF資源。建立映像資源時,軟件會將映像數據直接加載到PDF輸出文件中。換句話說,圖像數據不駐留在存儲器中,容許大量的圖像而不減小程序存儲器空間。PdfImage類有三個構造函數。
//從文件中加載圖片
PdfImage Image = new PdfImage(PdfDocument Document, String ImageFileName, PdfImageControl ImageControl);
// 從內存中加載圖片(Image,Bitmap)
PdfImage Image = new PdfImage(PdfDocument Document, Image MemoryImage, PdfImageControl ImageControl);
// 加載二進制
PdfImage Image = new PdfImage(PdfDocument Document, Boolean[,] BWImage, PdfImageControl ImageControl);
參數是:
Document
:PdfDocument
PDF文檔的對象。
ImageFileName
:圖像文件是能夠加載到.NET Image
派生類的任何文件。圖像派生類是Bitmap
光柵圖像或Metafile
矢量圖像的圖像。若是輸入文件名,擴展名爲.emf或.wmf,則將文件加載到文件中Metafile
,不然文件將加載到Bitmap
。
MemoryImage
:是位圖或由應用程序在內存中建立的元文件。
BWImage
:是一個布爾二維數組。False表示黑色,true表示白色。PdfQRCode類使用此格式來表示QR圖像。
ImageControl
:是一個可選參數,用於保存圖像建立屬性。
PdfImageControl
具備如下屬性。全部屬性都是可選的。
SaveAs
:圖片另存爲Jpeg
,IndexedImage
,GrayImage
或BWImage
。
CropRect
:裁剪矩形是定義要裁剪的圖像區域的矩形。注意:矩形座標是.net標準。原點在左上角,Y軸朝下。裁剪矩形能夠Rectangle
。在這種狀況下,尺寸以像素爲單位。裁剪矩形必須包含在圖像中。
CropPercent
:如上所示裁剪矩形,但尺寸以圖像寬度和高度的百分比表示。
Resolution
:圖像分辨率設置圖像分辨率,前提是它小於源圖像的分辨率。分辨率以每英寸像素爲單位指定。減少的分辨率意味着較小的PDF文件。
ImageQuality
:它是一個在0到100範圍內的整數,表示質量差到最佳質量的圖像,或DefaultQuality
(-1)表示以默認質量保存圖像。較低的圖像質量意味着較小的PDF文件。若是圖像質量未定義,則將其視爲默認質量。.net框架工做默認保存方法使用的質量因子爲75.此編號不禁Microsoft記錄。它是經過實驗和互聯網搜索計算的。
GrayToBWCutoff
:將位圖轉換爲黑白是兩步過程。第一種是標準顏色到灰色陰影。若是灰度陰影低於截止,則第二個將像素設置爲黑色,若是灰度低於截止,則將像素設置爲白色。有效值爲1到99。
ReverseBW
:在灰色或BW圖像中,若是此屬性爲true,則顏色反轉。
其餘方法PdfImage
。
該ImageSize
方法返回具備適合給定區域的正確寬高比的最大矩形。
SizeD ImageSize(Double Width, Double Height);
該ImageSizePosition
方法返回具備適合給定區域的正確寬高比的最大矩形,並基於ContentAlignment
枚舉對其進行定位。
ImageSizePos ImageSizePosition(Double Width, Double Height, ContentAlignment Alignment);
最後將圖像繪製成內容使用DrawImage
方法。若是您但願圖像保持正確的寬高比使用ImageSize
或ImageSizePosition
計算寬度和高度。若是寬度和高度的比率與圖像不一樣,則圖像將看起來在一個方向上拉伸。
Contents.DrawImage(Image, PosX, PosY, Width, Height);
應當指出的是,除了PdfImage
,PdfQRCode
,PdfChart
和PrintPdfDocument
產生PDF文檔中PDF圖像
2.5 條形碼支持
下面的代碼說明了如何在PDF文檔中包含UPC-A條形碼。
// 建立對象
BarcodeEAN13 Barcode = new BarcodeEAN13("123456789010");
// 繪製條形碼
Contents.DrawBarcode(PosX, PosY, BarWidth, BarcodeHeight, Barcode, Font, FontSize);
在這種狀況下,類是具備12位數字輸入字符串的BarcodeEAN13。結果是UPC-A條形碼。
PDF文件編寫器庫包括基類Barcode
。對於每一個支持的條形碼,須要一個派生類。類庫包括四個子類:Barcode128
,Barcode39
,BarcodeInterleaved2of5
和BarcodeEAN13
。該BarcodeEAN13
生產EAN-13條碼,若是輸入字符串爲13位數字和UPC-A若是輸入字符串爲12位。具備13位數字和前導零的輸入字符串被認爲是UPC-A。
該DrawBarcode
方法具備多個重載。您能夠指定條形碼左下角的位置,窄條的寬度,條形碼的高度以及導出的條形碼類別。有可選參數:對齊(左,中,右)顏色和字體以顯示文本。條形碼周圍的安靜區域是您的責任。可選文本顯示在條形碼下方。若是你選擇的顏色不是黑色,你應該確保背景的對比是顯着的。用法示例中給出3.7繪製條形碼,ArticleExample.cs
和OtherExample.cs
。
若是要爲另外一個條形碼建立派生類,請使用三個包含的類的源代碼做爲示例。
2.6 加密支持
PDF文件編寫器庫支持AES 128和標準128(RC4)加密。有關詳細信息,請參閱PDF參考第六版(1.7版)第3.5節加密。PDF文件編寫器支持兩種類型的加密過濾器,AES-128和128.標準128是RC4加密。它被認爲不安全。對於新項目不使用它。它不支持公鑰密碼編碼收件人列表。
要加密PDF文檔,請調用類中SetEncryption
定義的四種方法之一PdfDocument
:
1.設置不帶參數的加密。
PDF文件編寫器庫將使用AES-128加密來加密PDF文檔。PDF閱讀器將打開文檔,而無需請求密碼。權限標誌設置爲容許全部。
Document.SetEncryption();
2.使用一個參數設置加密。
PDF文件編寫器庫將使用AES-128加密來加密PDF文檔。參數是權限。權限標誌定義以下。你能夠或者一塊兒得到多個權限。PDF參考手冊有完整的權限描述。PDF閱讀器將打開文檔,而無需請求密碼。
Document.SetEncryption(Permission Permissions);
3.使用兩個參數設置加密。
PDF文件編寫器庫將使用AES-128加密來加密PDF文檔。兩個參數是用戶密碼和權限。PDF閱讀器將使用用戶密碼打開文檔。權限將根據參數設置。
Document.SetEncryption(String UserPassword, Permission Permissions);
4.使用四個參數設置加密。
PDF文件編寫器庫將使用EncryptionType.Aes128加密或EncryptionType.Standard128加密來加密PDF文檔。四個參數是用戶密碼,全部者密碼,權限和加密類型。若是用戶密碼爲空,將採用默認密碼。若是全部者密碼爲null,則軟件會生成隨機數密碼。Standard128加密被認爲不安全。它不該該用於新項目。
諸如Acrobat的PDF閱讀器將接受用戶或全部者密碼。若是使用全部者密碼打開文檔,PDF閱讀器將打開它,並將全部權限設置爲容許操做。
Document.SetEncryption(String UserPassword, String OwnerPassword, Permission Permissions, EncryptionType Type);
權限標誌以下:
//全描述引用1.7版本表3.20
public enum Permission
{
None = 0,
LowQalityPrint = 4, // bit 3
ModifyContents = 8, // bit 4
ExtractContents = 0x10, // bit 5
Annotation = 0x20, // bit 6
Interactive = 0x100, // bit 9
Accessibility = 0x200, // bit 10
AssembleDoc = 0x400, // bit 11
Print = 0x804, // bit 12 + bit 3
All = 0xf3c, // bits 3, 4, 5, 6, 9, 10, 11, 12
}
2.7 Web連接支持
PDF文件編寫器庫提供對Web連接的支持。此功能是PDF參考手冊第8節交互功能中描述的PDF交互功能之一。它是註釋和動做的組合。註釋將Web連接與頁面上的區域相關聯。當用戶點擊該區域時,PDF閱讀器將激活導航到指望的網頁的默認web瀏覽器。
註釋區域是由相對於頁面左下角的絕對座標定義的矩形區域。添加類的Web連接調用AddWebLink
方法PdfPage
。
Page.AddWebLink(Double LeftPos, Double BottomPos, Double RightPos, Double TopPos, String WebLink);
註釋不是頁面內容的一部分。爲了讓PDF文檔的讀者知道在哪裏點擊,您須要在頁面上的相同區域中顯示相應的文本或圖形。換句話說,你須要調用兩個方法。在AddWebLink
與網頁和與內容相關聯的第二方法相關聯的方法。第二種方法能夠是圖形對象,例如圖像或矩形或文本。由於AddWebLink
須要相對於頁面左下角的座標,因此圖形對象的座標必須相同。換句話說,不要使用平移,縮放或旋轉。若是你這樣作,你須要確保這兩個區域將重合。
PDF文件編寫器有幾種PdfContents
支持文本註釋的方法。
使用相關的網絡連接繪製一行文本。文本將左對齊,帶下劃線和藍色。文本位置相對於頁面的左下角。
PdfContents.DrawWebLink(PdfPage Page, PdfFont Font, Double FontSize,
Double TextAbsPosX, Double TextAbsPosY, String Text, String WebLink);
使用相關的網絡連接繪製一行文本。文本位置相對於頁面的左下角。
PdfContents.DrawWebLink(PdfPage Page, PdfFont Font, Double FontSize, Double TextAbsPosX, Double TextAbsPosY,
TextJustify Justify, DrawStyle DrawStyle, Color TextColor, String Text, String WebLink);
在其中繪製Web連接TextBox
是一個兩步過程。首先,使用類的一種AddText
方法將文本和Web連接字符串添加到框中TextBox
。第二個你繪製的TextBox
頁面內容使用的DrawText
方法之一PdfContents
。
添加網絡連接TextBox
。文本將顯示爲下劃線和藍色。
TextBox.AddText(PdfFont Font, Double FontSize, String Text, String WebLink);
添加網絡連接TextBox
。文本屬性由DrawStyle
和定義FontColor
。
TextBox.AddText(PdfFont Font, Double FontSize, DrawStyle DrawStyle, Color FontColor, String Text, String WebLink);
第二步繪製文本到內容。此方法假設沒有額外的行或段落間距。請注意,若是你調用DrawText
無PdfPage
參數上TextBox
有WebLink
信息,ApplicationException
將被拋出。
//PosYTop 能夠引用上一個元素的PointY位置
PdfContents.DrawText(Double PosX, ref Double PosYTop, Double PosYBottom, Int32 LineNo, TextBox Box, PdfPage Page);
此方法容許您定義額外的行或段落間距。請注意,若是你調用DrawText
無PdfPage
參數上TextBox
有WebLink
信息,ApplicationException
將被拋出。
PdfContents.DrawText(Double PosX, ref Double PosYTop, Double PosYBottom, Int32 LineNo,
Double LineExtraSpace, Double ParagraphExtraSpace, Boolean FitTextToWidth, TextBox Box, PdfPage Page);
有關編碼示例,請參閱3.4 Draw Frame,ArticleExample.cs和OtherExample.cs源代碼。
2.8 QR碼支持
從V1.7開始,PDF文件編寫器庫提供對QR碼的支持。該程序支持三個字符集:數字,字母數字和8位字節。程序不支持漢字字符。QR碼是圖像資源。庫將QR代碼內容轉換爲圖像。要在文檔中顯示QR碼,須要定義一個資源對象,並將此對象添加到頁面的內容。程序自動選擇最佳字符集和最佳矩陣大小。用戶必須提供數據字符串和所需的糾錯級別。錯誤校訂級別是:L低(7%),M中(15%),Q中中高(25%),H高(30%)。字符集定義爲:數字數據(數字0-9)。字母數字(數字0-9,大寫字母AZ和九個其餘字符空格$%* + - 。/:),8位字節數據。程序將掃描數據串輸入並選擇最有效的字符集。若是您的數據能夠分紅只有數字或只是字母數字字符的段,您能夠建立一個QR碼對象與數據字符串數組。
使用單個數據字符串建立QR代碼對象。
PdfQRCode QRCode = new PdfQRCode(PdfDocument Document, String DataString, ErrorCorrection ErrorCorrection);
或者,使用數據字符串數組建立QR Code對象。若是要將數據字符串分紅不一樣字符集的部分,請使用此形式。
PdfQRCode QRCode = new PdfQRCode(PdfDocument Document, String[] DataString, ErrorCorrection ErrorCorrection);
默認狀況下,建立的圖像將具備每一個QR碼模塊4×4像素和圖像周圍16個像素的安靜空間。要覆蓋默認使用:
QRCode.SetModuleSize(Int32 ModuleSize, Int32 QuietZone);
繪製QR碼調用DrawQRCode
方法PdfContents
。這QRCode
是一個正方形。寬度和高度相同。
Contents.DrawQRCode(PdfQRCode QRCode, Double OrigX, Double OrigY, Double Width);
有關編碼示例,請參閱3.7繪製條形碼,ArticleExample.cs和OtherExample.cs源代碼。
2.9 書籤支持
書籤在PDF規範(第8.2.2節「文檔大綱」)中描述以下:「PDF文檔能夠可選地在屏幕上顯示文檔大綱,容許用戶以交互方式從文檔的一個部分導航到另外一個部分。的樹結構層次結構的大綱項(有時稱爲書籤),其做爲內容的可視表以向用戶顯示文檔的結構。用戶能夠經過用鼠標點擊它們來交互地打開和關閉單個項。
OtherExample.cs源代碼具備書籤示例。在一個位置有三個層次的層次結構。您能夠在OtherExample.pdf文件中查看結果。
嚮應用程序添加書籤的第一步是:
// 文檔建立書籤
PdfBookmark BookmarkRoot = Document.GetBookmarksRoot();
此步驟激活文檔中的書籤,並返回根節點。
添加書籤相似於向窗體中添加控件。第一級書籤被添加到根。後續級別將添加到現有書籤。至少,您必須定義頁面上的標題,頁面,垂直位置以及打開的條目標誌。page是要去的頁面的PdfPage對象。YPos是相對於頁面左下角的垂直位置。若是較低級別的書籤是可見的,則打開條目標誌爲真,若是較低級別的書籤被隱藏,則爲假。默認狀況下,第一級始終可見。
// 書籤實例
PdfBookmark FirstLevel_1 = BookmarkRoot.AddBookmark("Chapter 1", Page, YPos, false);
PdfBookmark SecondLevel_11 = FirstLevel_1.AddBookmark("Section 1.1", Page, YPos, false);
PdfBookmark SecondLevel_12 = FirstLevel_1.AddBookmark("Section 1.2", Page, YPos, false);
PdfBookmark ThirdLevel_121 = SecondLevel_12.AddBookmark("Section 1.2.1", Page, YPos, false);
PdfBookmark ThirdLevel_122 = SecondLevel_12.AddBookmark("Section 1.2.2", Page, YPos, false);
PdfBookmark SecondLevel_13 = FirstLevel_1.AddBookmark("Section 1.3", Page, YPos, false);
PdfBookmark FirstLevel_2 = BookmarkRoot.AddBookmark("Chapter 2", Page, YPos, false);
PdfBookmark SecondLevel_21 = FirstLevel_2.AddBookmark("Section 2.1", Page, YPos, false);
PdfBookmark SecondLevel_22 = FirstLevel_2.AddBookmark("Section 2.2", Page, YPos, false);
AddBookmark()方法有四個重載變體:
// 基本的
public PdfBookmark AddBookmark
(
String Title, // bookmark title
PdfPage Page, // bookmark page
Double YPos, // bookmark vertical position relative to bottom left corner of the page
Boolean OpenEntries // true is display children. false hide children
)
//標題顏色和樣式
public PdfBookmark AddBookmark
(
String Title, // bookmark title
PdfPage Page, // bookmark page
Double YPos, // bookmark vertical position relative to bottom left corner of the page
Color Paint, // bookmark color. Coloe.Empty is display title in default color
TextStyle TextStyle, // bookmark text style: normal, bold, italic, bold-italic
Boolean OpenEntries // true is display children. false hide children
)
// PointX和縮放
public PdfBookmark AddBookmark
(
String Title, // bookmark title
PdfPage Page, // bookmark page
Double XPos, // bookmark horizontal position relative to bottom left corner of the page
Double YPos, // bookmark vertical position relative to bottom left corner of the page
Double Zoom, // Zoom factor. 1.0 is 100%. 0.0 is ignore zoom.
Boolean OpenEntries // true is display children. false hide children
)
// 完整
public PdfBookmark AddBookmark
(
String Title, // bookmark title
PdfPage Page, // bookmark page
Double XPos, // bookmark horizontal position relative to bottom left corner of the page
Double YPos, // bookmark vertical position relative to bottom left corner of the page
Double Zoom, // Zoom factor. 1.0 is 100%. 0.0 is ignore zoom.
Color Paint, // bookmark color. Coloe.Empty is display title in default color
TextStyle TextStyle, // bookmark text style: normal, bold, italic, bold-italic
Boolean OpenEntries // true is display children. false hide children
)
PdfBookmark
類暴露一個方法GetChild
。您能夠經過調用GetChild
一個或多個整數參數來獲取任何書籤。每一個參數是級別中子位置的零基本參數。例如GetChild(2)
第一級的第三項。GetChild(2, 3)
是第三個第一級項目的第四個第二級項目。
2.10。圖表支持
PDF規範沒有特定的圖表支持。PDF文件編寫器庫經過容許開發人員建立Microsoft Charting對象並將此對象做爲圖像繪製到PDF文件中來提供圖表支持。有關Microsoft圖表控件註釋MSDN庫文檔Visual Studio 2012圖表控件的詳細信息。圖表名稱空間的文檔在「 數據可視化圖表命名空間」中提供。附上ChartExample.cs有四個圖表的例子。若是您打算使用圖表,您須要添加System.Windows.Forms.Visualization對您的項目的引用。在每一個源模塊使用Chart你須要引用System.Windows.Forms.DataVisualization.Charting命名空間。
將圖表添加到PDF文檔是四個步驟的過程。
- 建立圖表對象。
- 建立PdfChart對象。
- 構建圖表。
- 繪製PdfChart到PdfContents。
建立圖表的推薦方法是使用PdfChart
對象的靜態方法。
// 參數:文檔對象,寬,高,分辨率
Chart MyChart = PdfChart.CreateChart(PdfDocument Document, Double Width, Double Height, Double Resolution);
你能夠Chart
本身實例化類。
Chart MyChart = new Chart();
MyChart.RenderingDpiY = 300; // example of 300 pixels per inch
MyChart.Width = 1950; // example of 6.5 inches in pixels
Mychart.Height = 1350; // example of 4.6 inches in pixels
接下來PdfChart
從Chart
上面建立一個。或者,您能夠覆蓋分辨率。
// resolution is optional. It will override the resolution set above.
PdfChart MyPdfChart = new PdfChart(PdfDocument Document, Chart MyChart, Double Resolution);
接下來,您構建您的圖表。ChartExample.cs
有四個例子。構建圖表的文檔超出了本文的範圍。互聯網上有不少例子。
PdfChart
有一種CreateFont
方法來簡化字體的建立。它將基於圖表的分辨率計算字體大小。
// FontSizeUnit is an enumeration
// Available units: pixel, point, UserUnit, Inch, cm, mm
Font CreateFont(String FontFamilyName, FontStyle Style, Double FontSize, FontSizeUnit Unit);
最後一步是繪製圖表。
// Draw the chart at OrigX, OrigY in user units
// The width and height of the chart are taken from the Chart object.
// They are calculated from the size in pixels and resolution of the chart.
public void PdfContents.DrawChart(PdfChart MyPdfChart, Double OrigX, Double OrigY);
// Draw the chart at OrigX, OrigY with Width and Height as specified, all in user units.
// NOTE: Width and Height should be selected to agree with the aspect ratio of the chart object.
public void PdfContents.DrawChart(PdfChart MyPdfChart, Double OrigX, Double OrigY, Double Width, Double Height);
本PdfChart
類提供了一些可選的方法來控制圖像的定位。
該ImageSize
方法返回具備適合給定區域的正確寬高比的最大矩形。
SizeD ImageSize(Double Width, Double Height);
該ImageSizePosition
方法返回具備適合給定區域的正確寬高比的最大矩形,並基於ContentAlignment
枚舉對其進行定位。
ImageSizePos ImageSizePosition(Double Width, Double Height, ContentAlignment Alignment);
2.11 打印文檔支持
打印文檔支持容許您以打印到打印機和生成PDF文檔的相同方式打印報告。這種產生PDF文件的方法和PdfContents
用於產生PDF文件的方法之間的區別在於柵格圖形與矢量圖形之間的差別。打印文檔支持每頁建立一個jpeg圖像。PrintExample.cs
有建立三頁文檔的示例。
一般每一個頁面是頁面的完整圖像。若是您的頁面是Letter 尺寸,分辨率爲每英寸300像素,每一個像素爲3個字節,頁面的位圖將是25.245MB長。PrintPdfDocument
具備CropRect
能夠顯着減少位圖的大小的方法。假設使用一英寸邊距,位圖的活動大小將減小到15.795 MB。減小37.4%。
// main program
// Create empty document
Document = new PdfDocument(PaperType.Letter, false, UnitOfMeasure.Inch);
// create PrintPdfDocument producing an image with 300 pixels per inch 建立一個300像素每英寸的PrintPdfDocument
PdfImageControl ImageControl = new PdfImageControl();
ImageControl.Resolution = 300.0;
PrintPdfDocument Print = new PrintPdfDocument(Document, ImageControl);
// PrintPage in the delegate method PrintPageEventHandler
// This method will print one page at a time to PrintDocument
Print.PrintPage += PrintPage;
// set margins in user units (Left, top, right, bottom) 邊距設置
// note the margins order are per .net standard and not PDF standard
Print.SetMargins(1.0, 1.0, 1.0, 1.0);
// crop the page image result to reduce PDF file size //縮小尺寸
// the crop rectangle is per .net standard.
// The origin is top left. 原點在左上方
Print.CropRect = new RectangleF(0.95F, 0.95F, 6.6F, 9.1F);
// initiate the printing process (calling the PrintPage method)啓動打印進程
// after the document is printed, add each page as an image to PDF file.在打印完文檔以後,將每一個頁面做爲一個圖像添加到PDF文件中。
Print.AddPagesToPdfDocument();
// dispose of the PrintDocument object
Print.Dispose();
// create the PDF file
Document.CreateFile(FileName);
PrintPage方法的示例
// Print each page of the document to PrintDocument class打印文檔的每一頁的PrintDocument類
// You can use standard PrintDocument.PrintPage(...) method.
// NOTE: The graphics origin is top left and Y axis is pointing down.圖形原點是左上角,Y軸指向下方
// In other words this is not PdfContents printing.換句話說,這不是PdfContents的打印
public void PrintPage(object sender, PrintPageEventArgs e) {
// graphics object short cut Graphics G = e.Graphics;
// Set everything to high quality
G.SmoothingMode = SmoothingMode.HighQuality;
G.InterpolationMode = InterpolationMode.HighQualityBicubic;
G.PixelOffsetMode = PixelOffsetMode.HighQuality;
G.CompositingQuality = CompositingQuality.HighQuality;
// print area within margins
Rectangle PrintArea = e.MarginBounds;
// draw rectangle around print area
G.DrawRectangle(Pens.DarkBlue, PrintArea);
// line height
Int32 LineHeight = DefaultFont.Height + 8;
Rectangle TextRect = new Rectangle(PrintArea.X + 4, PrintArea.Y + 4, PrintArea.Width - 8, LineHeight);
// display page bounds
// DefaultFont is defined somewhere else
String text = String.Format("Page Bounds: Left {0}, Top {1}, Right {2}, Bottom {3}", e.PageBounds.Left, e.PageBounds.Top, e.PageBounds.Right, e.PageBounds.Bottom);
G.DrawString(text, DefaultFont, Brushes.Black, TextRect); TextRect.Y += LineHeight;
// display print area
text = String.Format("Page Margins: Left {0}, Top {1}, Right {2}, Bottom {3}",
PrintArea.Left, PrintArea.Top, PrintArea.Right, PrintArea.Bottom);
G.DrawString(text, DefaultFont, Brushes.Black, TextRect); TextRect.Y += LineHeight;
// print some lines
for(Int32 LineNo = 1; ; LineNo++)
{
text = String.Format("Page {0}, Line {1}", PageNo, LineNo);
G.DrawString(text, DefaultFont, Brushes.Black, TextRect);
TextRect.Y += LineHeight;
if(TextRect.Bottom > PrintArea.Bottom)
break;
}
// move on to next page
PageNo++;
e.HasMorePages = PageNo <= 3;
return; }
2.12 數據表(table)支持
數據表類容許您在PDF文檔中顯示數據表。PdfTable
是控制一個表的顯示的主類。表由標題行和數據行組成。每行被劃分爲單元格。PdfTableCell
控制一個標題單元或一個數據單元的顯示。若是使用頭,它將顯示在表的頂部。可選地,它將顯示在每一個附加頁面的頂部。要在單元格中顯示數據,請將數據加載到的Value
屬性中PdfTableCell
。數據能夠是:文本字符串,基本數值,布爾,字符TextBox
,圖像,QR碼或條形碼。獨立於數據,您能夠加載文檔連接,網絡連接,視頻,音頻或嵌入文件的單元格。單擊單元格區域內的任何位置將使PDF閱讀器激活文檔連接,網絡連接,視頻,音頻或嵌入式文件。數據的顯示由PdfTableStyle
類控制。PdfTable
類包含默認單元格樣式和默認標題樣式。您能夠覆蓋其中的私有樣式的默認樣式PdfTableCell
。要顯示錶,請建立一個PdfTable
對象。接下來,您將初始化表,標題單元格,數據單元格和樣式對象。最後,設置一個循環並加載一行的單元格值,而後繪製此行。此循環繼續,直到顯示全部數據。下面您將看到生成表所需的步驟順序。
調用DrawRow
方法時,軟件計算所需的行高。行高是最高單元格的高度。若是表中有足夠的空間,將繪製該行。當底部的可用空間過小時,將調用新頁面,而且可選標題和當前行顯示在表格的頂部。若是所需的行高度過大,將不適合全空表,則會引起異常。爲了適應長多行字符串,或TextBoxes
軟件能夠靈活地處理這些狀況。多行字符串由PdfTabl
e轉換爲a TextBox
。本PdfTableStyle
類有一個TextBoxPageBreakLines
屬性。若是此屬性設置爲零(默認值),則將TextBox
其視爲其餘數據值。TextBox
高度必須適合頁面。若是TextBoxPageBreakLines
設置爲正整數,系統將計算單元格的高度做爲TextBox
高度或高度的前幾行指定TextBoxPageBreakLines
。系統將繪製具備適合頁面的行數的行。將建立一個新頁面,並繪製其他的線條。換句話說,long的第一行塊TextBox
將至少是TextBoxPageBreakLines
長的。TableExample.cs源包含長TextBox
單元格的示例。
建立PdfTable
對象。
// create table
PdfTable Table = new PdfTable(Page, Contents, Font, FontSize);
page是當前的PdfPage。內容是當前的PdfContents。Font是表默認字體。FontSize是以點爲單位的默認字體大小。
在頁面上定義表的區域。
// table's area on the page
Table.TableArea = new PdfRectangle(Left, Bottom, Right, Top);
// first page starting vertical position
Table.RowTopPosition = StartingTopPosition;
四個參數是表格相對於左下角和用戶單位的四邊。若是在第一頁上,表頂部位置不在設置RowTopPosition
爲開始頂部位置的頁面的頂部。在後續頁面上,表格將始終從頂部開始。若是TableArea
未指定,庫將其設置爲默認頁面大小減小1英寸邊距。
將表寬度劃分爲列。
// divide table area width into columns
StockTable.SetColumnWidth(Width1, Width2, Width3, ...);
參數的數量是列數。表格寬度減去總邊界線將與這些參數成比例。
一旦使用SetColumnWidth
方法設置列的數量,庫將建立兩個PdfTableCell
數組。一個用於標題單元的數組和一個用於數據單元的數組。
數據表的行和列能夠用邊框線分隔。邊框線屬性由PdfTableBorder
和定義PdfTableBorderStyle
。有四個水平邊框線:TopBorder
,BottomBorder
,HeaderHorBorder
標題行和第一個數據行之間以及CellHorBorder
數據行之間。有兩組垂直邊框線:HeaderVertBorder
用於標題行CellVertBorder
中的垂直邊框線的數組,以及用於表的數據部分中的列之間的垂直邊框線的數組。數組大小是列數加一。數組元素零是表的左邊框。數組元素列是表的右邊框。全部其餘元素是分隔列的行。這些行中的每一行能夠單獨定義。有一些方法能夠一次定義全部邊界線,或定義每一個單獨的邊界線。
定義全部邊框線的方法:
// clear all border lines
Table.Borders.ClearAllBorders();
// set all border lines to default values (no need to call)
// All frame lines are one point (1/72") wide
// All grid lines are 0.2 of one point wide
// All borders are black
Table.Borders.SetDefaultBorders();
// set all borders to same width and black color
Table.Borders.SetAllBorders(Double Width);
// set all borders to same width and a specified color
Table.Borders.SetAllBorders(Double Width, Color LineColor);
// set all borders to one width and all grid lines to another width all lines are black
Table.Borders.SetAllBorders(Double FrameWidth, Double GridWidth);
// set all borders to one width and color and all grid lines to another width and color
Table.Borders.SetAllBorders(Double FrameWidth, Color FrameColor, Double GridWidth, Color GridColor);
// set all frame borders to same width and black color and clear all grid lines
Table.Borders.SetFrame(Double Width);
// set all frame borders to same width and a specified color and clear all grid lines
Table.Borders.SetFrame(Double Width, Color LineColor);
能夠清除或設置每一個水平邊界線。示例是頂部邊框線:
// clear border
Table.Borders.ClearTopBorder();
// set border with default color set to black
// Zero width means one pixel of the output device.
Table.Borders.SetTopBorder(Double LineWidth);
// set border
Table.Borders.SetTopBorder(Double LineWidth, Color LineColor);
能夠清除或設置每一個垂直邊界線。示例是單元格的垂直邊框線:
// clear border
Table.Borders.ClearCellVertBorder(Int32 Index);
// set border with default color set to black
Table.Borders.SetCellVertBorder(Int32 Index, Double LineWidth);
// set border
Table.Borders.SetCellVertBorder(Int32 Index, Double LineWidth, Color LineColor);
設置其餘可選的表屬性。下面的示例中給出的值是默認值。
// header on each page
HeaderOnEachPage = true;
// minimum row height
MinRowHeight = 0.0;
表信息每次處理一行。每行由單元格組成。每列一個單元格。單元格信息的顯示由PdfTableStyle
類控制。有大約20個樣式屬性。對於完整的列表視圖的源代碼或幫助文件。這些樣式中的一些特定於要顯示的信息的類型。這裏是一個例子
// make some changes to default header style
Table.DefaultHeaderStyle.Alignment = ContentAlignment.BottomRight;
// create private style for header first column
Table.Header[0].Style = Table.HeaderStyle;
Table.Header[0].Style.Alignment = ContentAlignment.MiddleLeft;
// load header value
Table.Header[0].Value = "Date";
// make some changes to default cell style
Table.DefaultCellStyle.Alignment = ContentAlignment.MiddleRight;
Table.DefaultCellStyle.Format = "#,##0.00";
// create private style for date column
Table.Cell[0].Style = StockTable.CellStyle;
Table.Cell[0].Style.Alignment = ContentAlignment.MiddleLeft;
Table.Cell[0].Style.Format = null;
初始化完成後,顯示數據。下面的例子是從TableExample.cs
。這是一張股票價格表。有6列。
// open stock daily price
StreamReader Reader = new StreamReader("SP500.csv");
// ignore header
Reader.ReadLine();
// read all daily prices
for(;;)
{
String TextLine = Reader.ReadLine();
if(TextLine == null) break;
String[] Fld = TextLine.Split(new Char[] {','});
Table.Cell[ColDate].Value = Fld[ColDate];
Table.Cell[ColOpen].Value = Double.Parse(Fld[ColOpen], NFI.PeriodDecSep);
Table.Cell[ColHigh].Value = Double.Parse(Fld[ColHigh], NFI.PeriodDecSep);
Table.Cell[ColLow].Value = Double.Parse(Fld[ColLow], NFI.PeriodDecSep);
Table.Cell[ColClose].Value = Double.Parse(Fld[ColClose], NFI.PeriodDecSep);
Table.Cell[ColVolume].Value = Int32.Parse(Fld[ColVolume]);
StockTable.DrawRow();
}
StockTable.Close();
該DrawRow(NewPage)
方法具備可選參數Boolean NewPage = false
。默認值爲false
。若是但願下一行打印在下一頁的頂部,請將參數設置爲true
。
交互功能示例。
// set cell number 6 with web link
BookList.Cell[6].WebLink = WebLinkString;
// another way to set weblink
BookList.Cell[6].AnnotAction = new AnnotWebLink(WebLinkString);
// set cell with document link to chapter 3
BookList.Cell[6].AnnotAction = new AnnotLinkAction("Chapter3");
// play video
PdfDisplayMedia Omega = new PdfDisplayMedia(PdfEmbeddedFile.CreateEmbeddedFile(Document, "Omega.mp4"));
BookList.Cell[6].AnnotAction = new AnnotDisplayMedia(Omega);
// play audio
PdfDisplayMedia RingSound = new PdfDisplayMedia(PdfEmbeddedFile.CreateEmbeddedFile(Document, "Ring01.wav"));
BookList.Cell[6].AnnotAction = new AnnotDisplayMedia(RingSound);
// allow user to save or view embedded file
PdfEmbeddedFile EmbeddedFile = PdfEmbeddedFile.CreateEmbeddedFile(Document, "BookList.txt");
BookList.Cell[6].AnnotAction = new AnnotFileAttachment(EmbeddedFile, FileAttachIcon.NoIcon);
對於數據表的源代碼,更多的例子看看ArticleExample.cs
和TableExample.cs
。有關,和類的更多詳細信息PdfTable
,請查看幫助文件。PdfTableCell
PdfTableStyle
PdfTableBorder
PdfFileWriter.chm
2.13 播放視頻文件
該PdfFileWriter
支持嵌入PDF文檔中的視頻文件。播放視頻文件的完整示例在第7頁OtherExample.cs
。添加視頻文件須要使用三個類。
首先,您須要將視頻文件嵌入到PDF文檔中。
第二,你須要定義如何播放視頻。的PdfDisplayMedia
類有許多方法來控制視頻顯示。請參考類的源代碼和文檔幫助文件。例如:RepeatCount
或ScaleMedia
。若是要在浮動窗口中播放視頻,您必須使 用SetMediaWindow
方法。
第三,您須要在PDF頁面上定義用戶必須單擊以激活視頻的區域。若是要在註釋區域可見時激活視頻,請使用ActivateActionWhenPageIsVisible
。
// define annotation rectangle that has the same aspect ratio as the video
PdfRectangle AnnotRect = ImageSizePos.ImageArea(480, 360,
AreaLeft, AreaBottom, AreaRight - AreaLeft, AreaTop - AreaBottom, ContentAlignment.MiddleCenter);
// create display media object
PdfDisplayMedia DisplayMedia = new PdfDisplayMedia(PdfEmbeddedFile.CreateEmbeddedFile(Document, "LooneyTunes.mp4"));
// create annotation object
PdfAnnotation Annotation = Page.AddScreenAction(AnnotRect, DisplayMedia);
// activate the video when the page becomes visible
// Annotation.ActivateActionWhenPageIsVisible(true);
// define X Object to paint the annotation area when the video is not playing
PdfXObject AnnotArea = AnnotationArea(AnnotRect.Width, AnnotRect.Height, Color.Lavender, Color.Indigo, "Click here to play the video");
Annotation.Appearance(AnnotArea);
浮動窗口視頻顯示
// create display media object
PdfDisplayMedia DisplayMedia = new PdfDisplayMedia(PdfEmbeddedFile.CreateEmbeddedFile(Document, "Omega.mp4"));
// activate display controls
DisplayMedia.DisplayControls(true);
// repeat video indefinitly
DisplayMedia.RepeatCount(0);
// display in floating window
DisplayMedia.SetMediaWindow(MediaWindow.Floating, 640, 360, WindowPosition.Center,
WindowTitleBar.TitleBarWithCloseButton, WindowResize.KeepAspectRatio, "Floating Window Example");
Double LineSpacing = ArialNormal.LineSpacing(12.0);
Double TextPosX = PosX + 0.5 * AreaWidth;
Double TextPosY = PosY + 0.5 * AreaHeight + LineSpacing;
Double TextWidth = Contents.DrawText(ArialNormal, 12.0, TextPosX, TextPosY, TextJustify.Center, "Click this text to play video");
TextPosY -= LineSpacing;
Contents.DrawText(ArialNormal, 12.0, TextPosX, TextPosY, TextJustify.Center, "in floating window");
// create annotation object
PdfRectangle AnnotRect = new PdfRectangle(TextPosX - 0.5 * TextWidth, TextPosY - ArialNormal.DescentPlusLeading(12.0),
TextPosX + 0.5 * TextWidth, TextPosY + ArialNormal.AscentPlusLeading(12.0) + LineSpacing);
Page.AddScreenAction(AnnotRect, DisplayMedia);
2.14 播放聲音文件
該PdfFileWriter
支持嵌入PDF文檔中的聲音文件。播放聲音文件的完整示例在第7頁中給出OtherExample.cs
。嵌入聲音文件與視頻文件基本相同。惟一明顯的區別是沒有什麼能夠顯示。
// create embedded media file
PdfDisplayMedia DisplayMedia = new PdfDisplayMedia(PdfEmbeddedFile.CreateEmbeddedFile(Document, "Ring01.wav"));
DisplayMedia.SetMediaWindow(MediaWindow.Hidden);
AnnotDisplayMedia RingSound = new AnnotDisplayMedia(DisplayMedia);
// display text area to activate the sound
Double LineSpacing = ArialNormal.LineSpacing(12.0);
Double TextPosX = PosX + 0.5 * AreaWidth;
Double TextPosY = PosY + 0.5 * AreaHeight + LineSpacing;
Contents.DrawTextWithAnnotation(Page, ArialNormal, 12.0, TextPosX, TextPosY, TextJustify.Center,
DrawStyle.Normal, Color.Red, "Click this text to play", RingSound);
TextPosY -= LineSpacing;
Contents.DrawTextWithAnnotation(Page, ArialNormal, 12.0, TextPosX, TextPosY, TextJustify.Center,
DrawStyle.Normal, Color.Red, "Ringing sound", RingSound);
2.15 附加數據文件
在PdfFileWriter
支持PDF文檔中嵌入數據文件。嵌入文件的完整示例在第7頁中給出OtherExample.cs
。用戶能夠保存文件或顯示文件。
// create embedded media file
PdfEmbeddedFile EmbeddedFile = PdfEmbeddedFile.CreateEmbeddedFile(Document, "BookList.txt");
AnnotFileAttachment FileIcon = new AnnotFileAttachment(EmbeddedFile, FileAttachIcon.Paperclip);
// display text area to activate the file attachment
Double LineSpacing = ArialNormal.LineSpacing(12.0);
Double TextPosX = PosX + 0.5 * AreaWidth;
Double TextPosY = PosY + 0.5 * AreaHeight + LineSpacing;
Contents.DrawText(ArialNormal, 12.0, TextPosX, TextPosY, TextJustify.Center, "Right click on the paper clip");
TextPosY -= LineSpacing;
Double TextWidth = Contents.DrawText(ArialNormal, 12.0, TextPosX, TextPosY, TextJustify.Center, "to open or save the attached file");
// annotation
Double IconPosX = TextPosX + 0.5 * TextWidth + 0.1;
Double IconPosY = TextPosY;
PdfRectangle AnnotRect = new PdfRectangle(IconPosX, IconPosY, IconPosX + 0.15, IconPosY + 0.4);
Page.AddFileAttachment(AnnotRect, EmbeddedFile, FileAttachIcon.Paperclip);
TextPosY -= 2 * LineSpacing;
AnnotFileAttachment FileText = new AnnotFileAttachment(EmbeddedFile, FileAttachIcon.NoIcon);
Contents.DrawTextWithAnnotation(Page, ArialNormal, 12.0, TextPosX, TextPosY, TextJustify.Center,
DrawStyle.Underline, Color.Red, "File attachment (right click)", FileText);
2.16 從新排序頁面
在PdfFileWriter
追加新的網頁頁面列表的末尾。若是要將頁面從當前位置移動到新位置,請使用如下方法。
Document.MovePage(Int32 SourceIndex, Int32 DestinationIndex);
2.17 PDF文檔輸出
PdfFileWriter建立PDF文檔。主類PdfDocument構造函數給你兩個選擇來保存文檔。第一種選擇是將PDF文件保存到磁盤文件。在這種狀況下,你提供了一個文件名。在文件建立結束時調用PdfDocument.CreateFile。
此方法將PDF寫入文件並關閉文件。
// create main class
PdfDocument Document = new PdfDocument(PaperType.Letter, false, UnitOfMeasure.Inch, FileName);
// terminate
Document.CreateFile();
第二個選擇是流。您建立一個流,內存流或文件流,並將該流做爲參數傳遞給PdfDocument構造函數。執行CreateFile方法後,您的流包含PDF文檔。根據應用程序,從流中提取文檔。您必須在應用程序中關閉流。
// create memory stream
MemoryStream PdfStream = new MemoryStream();
// create main class
PdfDocument Document = new PdfDocument(PaperType.Letter, false, UnitOfMeasure.Inch, PdfStream);
// terminate
Document.CreateFile();
// save the memory stream to a file
FileStream FS = new FileStream(FileName, FileMode.Create);
PdfStream.WriteTo(FS);
PdfStream.Close();
FS.Close();
2.18 文檔信息字典
PDF文檔信息字典由PDF閱讀器在文檔屬性的「說明」選項卡中顯示。信息包括:標題,做者,主題,關鍵字,建立的日期和時間,修改的日期和時間,生成文件的應用程序,PDF生成器。
在應用程序中包含文檔信息的步驟以下:
PdfInfo Info = new PdfInfo(Document);
Info.Title("Article Example");
Info.Author("Uzi Granot Granotech Limited");
Info.Keywords("PDF, .NET, C#, Library, Document Creator");
Info.Subject("PDF File Writer C# Class Library (Version 1.15.0)");
當PdfInfo
對象被建立,四個額外的字段被添加到詞典中。您能夠在代碼中覆蓋全部這些。
// set creation and modify dates
DateTime LocalTime = DateTime.Now;
Info.CreationDate(LocalTime);
Info.ModDate(LocalTime);
// set creator and producer
Info.Creator("PdfFileWriter C# Class Library Version " + PdfDocument.RevisionNumber);
Info.Producer("PdfFileWriter C# Class Library Version " + PdfDocument.RevisionNumber);
2.19 內存控制
在構建文檔時,PDF文件編寫器會累積建立PDF文件所需的全部信息。信息保存在內存中,除了圖像和嵌入文件。圖像和嵌入文件在聲明時會自動寫入輸出文件。對於很是大的文檔,使用的內存不斷增加。庫提供方法(CommitToPdfFile
)將內容信息寫入輸出文件,並調用垃圾收集器釋放未使用的內存。該GC.Collect
方法須要時間來執行。若是執行時間是問題,請GCCollect
每幾頁設置一次參數。換句話說,CommitToPdfFile
必須針對每一個頁面運行,但每幾頁清理一次。執行提交後,不能添加其餘信息。PdfTable
當下一行不能容納在當前頁面的底部時自動啓動新頁面。該PdfTable
班有兩個成員CommitToPdfFile
,並CommitGCCollectFreq
同時表被構建以控制內存的使用狀況。本PdfChart
類生成從.NET類圖的圖像。該DrawChart
方法PdfContents
將執行提交。或者,您能夠調用的CommitToPdfFile
方法PdfChart
。
// PdfContents, PdfXObject and PdfTilingPattern
// Commit the contents to output file.
// Once committed, this PdfContents cannot be used.
// The argument is GCCollect
Contents.CommitToPdfFile(true);
2.20 Windows Presentation Foundation WPF
繪製WPF圖形是一個四個步驟的過程。
- 步驟1:建立
DrawWPFPath
對象。輸入參數是路徑和Y軸方向。
- 步驟2:可選擇經過調用七種
SetBrush
方法之一或調用UseCurrentBrush
方法添加畫筆。
- 步驟3:可選擇經過調用兩種
SetPen
方法之一或調用UseCurrentPen
方法添加筆。
- 步驟4:經過調用繪製圖形對象
PdfContents.DrawWPFPath
。
若是System.Windows.Media
引用不可用(即您的應用程序是Windows窗體),則須要嚮應用程序添加PresentationCore
和WindowsBase
程序集。
Example8 OtherExample.cs
和Example8f 中給出了使用WPF圖形類繪製的編程示例。
若是未定義畫筆和筆,則繪製圖形將做爲剪輯路徑。
下面你會發現更多的細節如何使用DrawWPFPath類WPF應用程序和其餘應用程序。
DrawWPFPath
構造函數接受兩個參數:路徑和Y軸方向。路徑是字符串或System.Windows.Media.PathGeometry
。文本字符串在路徑標記語法中定義。路徑幾何類在PathGeometry類中進行了描述。當爲WPF環境定義路徑時,Y軸方向爲向下。Y軸適用於PDF環境。
注意世界任何地方的程序員使用除了句點以外的數字小數分隔符。表示路徑的文本字符串輸入必須徹底按照路徑標記語法中的定義來構造。具備分數的小數必須使用週期,而不考慮世界區域。若是在x和y值之間使用可選分隔符,它必須是逗號。若是字符串是由另外一個應用程序生成的,請確保使用PathGeometry.ToString(System.Globalization.CultureInfo.InvariantCulture)調用PathGeometry ToString。換句話說,Microsoft的PathGeometry.Parse方法將沒法讀取意大利產生的文本字符串,例如,經過PathGeometry.ToString方法,而不將IFormatProvider設置爲InvariantCulture。 |
有三種方法來爲WPF應用程序定義畫刷。全部這些方法將同時設置畫筆不透明度。
System.Windows.Media.SolidColorBrush
請參閱SolidColorBrush類
System.Windows.Media.LinearGradientBrush
請參閱LinearGradientBrush類
System.Windows.Media.RadialGradientBrush
請參閱RadialGradientBrush類
有五種方法爲全部應用程序定義畫筆。全部這些方法將同時設置畫筆不透明度。
- 將畫筆設置爲
System.Drawing.Color
。
- 將畫筆設置爲
PdfAxialShading
- 將畫筆設置爲
PdfRadialShading
- 將畫筆設置爲
PdfTilingPattern
- 將畫筆設置爲
UseCurrentBrush
若是你想讓DrawWPFPath
類將畫筆設置爲當前選擇的畫筆,調用UseCurrentBrush
方法。
有一種方法爲WPF應用程序定義筆。調用SetPen
方法與System.Windows.Media.Pen
類(請參閱 Pen類)。注意,Pen.Brush
屬性必須是SolidColorBrush
。筆類包含繪製線所需的全部信息,例如顏色和寬度。
有一種方法爲全部應用程序定義筆。調用SetPen
與System.Drawing.Color
參數。color參數定義了alpha,紅,綠和藍色份量。要設置其餘筆特性,請設置如下任何或所有屬性和方法:
SetPenWidth
DashArray
DashPhase
LineCap
LineJoin
MiterLimit
若是您但願DrawWPFPath
類將筆設置爲當前選擇的筆調用UseCurrentPen
方法。
一旦DrawWPFPath
類設置了繪製路徑所需的全部信息,調用PdfContents.DrawWPFPath
方法。DrawWPFPath類基於路徑邊界框和繪製矩形和對齊,計算將輸入路徑轉換爲繪圖矩形所需的變換矩陣。對齊零(默認值)將拉伸路徑以適合繪圖區域。全部其餘對齊值根據參數枚舉值在繪圖區域中定位路徑。
public void DrawWPFPath(
DrawWPFPath Path, // path to be drawn
double OriginX, // Drawing rectangle in user units left side
double OriginY, // Drawing rectangle in user units bottom side
double Width, // Drawing rectangle in user units width
double Height, // Drawing rectangle in user units height
// path alignment within drawing rectangle
// Alignment=0 means the path will be stretched
// in either horizontal or vertical direction
// to fit the drawing rectangle
ContentAlignment Alignment = 0)
2.21 透明度,不透明度,Alpha顏色成分和混合
默認狀況下,PDF成像模型會將對象(形狀,線條,文本和圖像)不透明地繪製到頁面上。每一個新對象徹底掩蓋了它下面的圖像。PDF有兩種機制來改變這種行爲不透明度和混合。圖形狀態字典具備用於描邊(筆)和非描邊(刷)操做的不透明度值。徹底不透明的不透明度值爲1.0,徹底透明度爲0.0。不透明度值對應於顏色結構的α份量,使得1.0爲255,α爲0。若是不透明度值爲0.5,則在頁面上繪製的新對象將是50%透明的。要設置不透明度,請調用SetAlphaStroking
線或SetAlphaNonStroking
方法的形狀的方法。混合是將頁面上的顏色與正在繪製的新項目的顏色組合的過程。要設置一個bland模式調用的SetBlendMode
方法PdfContents
。參數是BlendMod
e枚舉。有關詳細說明,請參閱PDF規格文檔的7.2.4混合模式。例如,請參見OtherExample.cs
第8頁。
2.22 文檔連接和命名目標
文檔連接容許PDF文檔用戶單擊連接並跳轉到文檔的另外一部分。添加文檔連接分爲兩部分。目標定義爲位置標記。位置標記必須具備惟一的名稱,範圍(LocalDest
或NamedDest
)和文檔位置(頁面和位置)。NamedDest
範圍可用於文檔連接或命名目標或二者。第二部分是連接位置。這兩個部分能夠按任何順序定義。他們被綁在一塊兒的名字。名稱區分大小寫。許多連接能夠指向同一位置標記。
命名目標是PDF文檔中的目標。它們使用位置標記以與文檔連接相同的方式定義。範圍必須設置爲NamedDest
。當諸如Adobe Acrobat的PDF閱讀器打開PDF文檔時,它能夠在查看窗口中顯示目標時打開文檔。
要嵌入位置標記,調用的AddLocationMarker
方法PdfPage
。注意:名稱區分大小寫。
// Add location marker to the document (PdfPage method)
public void AddLocationMarker
(
string LocMarkerName, // unique destination name (case sensitive)
LocMarkerScope Scope, // eigther LocalDest or NamedDest
DestFit FitArg, // fit argument (see below)
params double[] SideArg // 0, 1 or 4 side dimension argument (see below)
)
添加連接位置調用PdfPage的AddLinkLocation方法。
public PdfAnnotation AddLinkAction
(
string LocMarkerName, // location marker name
PdfRectangle AnnotRect // rectangle area on the page to activate the jump
)
有關命名目的地的詳細信息,請參閱Adobe PDF文件規範「PDF參考,第六版,Adobe便攜式文檔格式版本1.7,2006年11月」。第582頁的表8.2。
DestFit.Fit
(無參數):顯示頁面,其內容放大恰好足以適合水平和垂直窗口內的整個頁面。
DestFit.FitH
(1 arg Top):顯示頁面,垂直座標頂部位於窗口的頂部邊緣,而且頁面的內容放大恰好足以適合窗口內頁面的整個寬度。
DestFit.FitV
(1 arg Left):顯示頁面,水平座標左邊位於窗口的左邊緣,頁面的內容放大恰好足以適合窗口內頁面的整個高度。
DestFit.FitR
(4 args Left Bottom Right Top):顯示頁面,其內容被放大,恰好足以適合由水平和垂直方向的窗口內的左,右,底和座標指定的矩形。
DestFit.FitB
(無參數):顯示頁面,其內容放大剛剛足以適合水平和垂直的窗口內的整個邊界框。
DestFit.FitBH
(1 arg Top):顯示頁面,垂直座標頂部位於窗口的頂部邊緣,頁面的內容放大恰好足以適合窗口內邊界框的整個寬度。
DestFit.FitBV
(1 arg Left):顯示頁面,水平座標左邊位於窗口的左邊緣,頁面的內容放大恰好足以適合窗口內其邊界框的整個高度。
PDF閱讀器的調用參數在Adobe的「打開PDF文件的參數」中定義。若是PDF在臺式計算機上打開,呼叫線路必須是:
「path \ AcroRd32.exe」/ A「nameddest = ChapterXX」「path \ Document.pdf」
若是PDF文檔由網頁中的連接指向,則目標將附加到連接:
<a href="http://example.org/Document.pdf#ChapterXX">目標說明</a>
或者:<a href="http://example.org/Document.pdf#namedsest=ChapterXX">目標說明</a>
2.23 安裝
集成PdfFileWriter
到您的應用程序須要如下步驟。PdfFileWriter.dll
在開發區域中安裝附加文件。啓動Visual C#程序並打開您的應用程序。轉到解決方案資源管理器,右鍵單擊引用,而後選擇添加引用。
選擇「瀏覽」選項卡,並將文件系統導航到的位置PdfFileWriter.dll
。當您的應用程序發佈時,必須包含代碼> PdfFileWriter.dll。
源代碼文檔做爲幫助文件提供PdfFileWriter.chm
。該文件由Sandcastle生成。結果看起來像Microsoft文檔頁。
若是要訪問PdfFileWriter
項目的源代碼,請PdfFileWriter
在開發區域中安裝項目。該PdfFileWriter.dll
會在PdfFileWriter\bin\Release
目錄中。
使用此庫將如下語句添加到全部源模塊。
若是您打算使用圖表,您須要添加引用:System.Windows.Forms.Visualization
。在每一個源模塊使用Chart
你須要添加
using System.Windows.Forms.DataVisualization.Charting;
3 實例開發指南
本節介紹PDF文件編寫器C#類庫到您的應用程序的集成。測試程序TestPdfFileWriter
程序是對本身的應用程序的模擬。當按下「文章示例」按鈕時,程序將執行ArticleExample.cs
源文件中的代碼。上圖顯示了生成的PDF文件。此方法演示瞭如何建立一個包含一些文本和圖形的頁面文檔。經過這個例子,你應該有一個很好的瞭解的過程。其餘示例按鈕生成各類PDF文檔。總的來講,實際上這個庫的每一個特徵都經過這些實施例來證實。
調試複選框(若是選中)將建立一個PDF文件,可使用文本編輯器查看,但沒法加載到PDF閱讀器。生成的文件未壓縮,圖像和字體文件將替換爲文本佔位符。調試複選框應僅用於調試。
TestPdfFileWriter程序是使用Microsoft Visual C#2012開發的。它已針對Windows XP,Vista,7和8進行了測試。
* 3.1 文檔建立概述
下面的測試方法演示了建立PDF文件的介紹中描述的六個步驟。當您按下演示程序的「文章示例」按鈕時,將執行該方法。如下小節詳細描述每一個步驟。
/// Create 「article example」 test PDF document
public void Test(Boolean Debug, String FileName)
{
// Step 1: Create empty document
// Arguments: page width: 8.5」, page height: 11」, Unit of measure: inches
// Return value: PdfDocument main class
Document = new PdfDocument(PaperType.Letter, false, UnitOfMeasure.Inch, FileName);
// for encryption test
// Document.SetEncryption(Permission.All & ~Permission.Print);
// Debug property
// By default it is set to false. Use it for debugging only.
// If this flag is set, PDF objects will not be compressed, font and images will be replaced
// by text place holder. You can view the file with a text editor but you cannot open it with PDF reader.
Document.Debug = Debug;
// Step 2: create resources
// define font resources
DefineFontResources();
// define tiling pattern resources
DefineTilingPatternResource();
// Step 3: Add new page
Page = new PdfPage(Document);
// Step 4:Add contents to page
Contents = new PdfContents(Page);
// Step 5: add graphics and text contents to the contents object
DrawFrameAndBackgroundWaterMark();
DrawTwoLinesOfHeading();
DrawHappyFace();
DrawBarcode();
DrawBrickPattern();
DrawImage();
DrawHeart();
DrawChart();
DrawTextBox();
DrawBookOrderForm();
// Step 6: create pdf file
// argument: PDF file name
Document.CreateFile();
// start default PDF reader and display the file
Process Proc = new Process();
Proc.StartInfo = new ProcessStartInfo(FileName);
Proc.Start();
// exit
return;
}
3.2 字體資源
該DefineFontResources
方法建立此示例中使用的全部字體資源。要查看可用於任何字體的全部字符,請按「字體家庭」按鈕。選擇一個族並查看爲每一個字符定義的字形。要查看單個字形按下視圖或雙擊。
// Define Font Resources
private void DefineFontResources()
{
// Define font resources
// Arguments: PdfDocument class, font family name, font style, embed flag
// Font style (must be: Regular, Bold, Italic or Bold | Italic) All other styles are invalid.
// Embed font. If true, the font file will be embedded in the PDF file.
// If false, the font will not be embedded
String FontName1 = "Arial";
String FontName2 = "Times New Roman";
ArialNormal = PdfFont.CreatePdfFont(Document, FontName1, FontStyle.Regular, true);
ArialBold = PdfFont.CreatePdfFont(Document, FontName1, FontStyle.Bold, true);
ArialItalic = PdfFont.CreatePdfFont(Document, FontName1, FontStyle.Italic, true);
ArialBoldItalic = PdfFont.CreatePdfFont(Document, FontName1, FontStyle.Bold | FontStyle.Italic, true);
TimesNormal = PdfFont.CreatePdfFont(Document, FontName2, FontStyle.Regular, true);
Comic = PdfFont.CreatePdfFont(Document, "Comic Sans MS", FontStyle.Bold, true);
return;
}
3.3 平鋪模式資源
該DefineTilingPatternResource
方法爲示例區域定義背景圖案資源。模式是在淺藍色背景白色的單詞「PdfFileWriter」。該模式由兩行重複關鍵字組成。這兩條線偏移半字長度。
若是你想找到有趣的模式,在互聯網上搜索公司的目錄製做floor或wall tiles
//// Define Tiling Pattern Resource
private void DefineTilingPatternResource()
{
// create empty tiling pattern
WaterMark = new PdfTilingPattern(Document);
// the pattern will be PdfFileWriter layed out in brick pattern
String Mark = "PdfFileWriter";
// text width and height for Arial bold size 18 points
Double FontSize = 18.0;
Double TextWidth = ArialBold.TextWidth(FontSize, Mark);
Double TextHeight = ArialBold.LineSpacing(FontSize);
// text base line
Double BaseLine = ArialBold.DescentPlusLeading(FontSize);
// the overall pattern box (we add text height value as left and right text margin)
Double BoxWidth = TextWidth + 2 * TextHeight;
Double BoxHeight = 4 * TextHeight;
WaterMark.SetTileBox(BoxWidth, BoxHeight);
// save graphics state
WaterMark.SaveGraphicsState();
// fill the pattern box with background light blue color
WaterMark.SetColorNonStroking(Color.FromArgb(230, 244, 255));
WaterMark.DrawRectangle(0, 0, BoxWidth, BoxHeight, PaintOp.Fill);
// set fill color for water mark text to white
WaterMark.SetColorNonStroking(Color.White);
// draw PdfFileWriter at the bottom center of the box
WaterMark.DrawText(ArialBold, FontSize, BoxWidth / 2, BaseLine, TextJustify.Center, Mark);
// adjust base line upward by half height
BaseLine += BoxHeight / 2;
// draw the right half of PdfFileWriter shifted left by half width
WaterMark.DrawText(ArialBold, FontSize, 0.0, BaseLine, TextJustify.Center, Mark);
// draw the left half of PdfFileWriter shifted right by half width
WaterMark.DrawText(ArialBold, FontSize, BoxWidth, BaseLine, TextJustify.Center, Mark);
// restore graphics state
WaterMark.RestoreGraphicsState();
return;}
3.4 畫與背景樣式的框架
該DrawFrameAndBackgroundWaterMark
方法在具備背景水印圖案的示例區域周圍繪製框架。模式資源在前面的小節中定義。
// Draw frame around example area
private void DrawFrameAndBackgroundWaterMark()
{
// save graphics state
Contents.SaveGraphicsState();
// Draw frame around the page
// Set line width to 0.02"
Contents.SetLineWidth(0.02);
// set frame color dark blue
Contents.SetColorStroking(Color.DarkBlue);
// use water mark tiling pattern to fill the frame
Contents.SetPatternNonStroking(WaterMark);
// rectangle position: x=1.0", y=1.0", width=6.5", height=9.0"
Contents.DrawRectangle(1.0, 1.0, 6.5, 9.0, PaintOp.CloseFillStroke);
// restore graphics sate
Contents.RestoreGraphicsState();
// draw article name under the frame
// Note: the \u00a4 is character 164 that was substituted during Font resource definition
// this character is a solid circle it is normally unicode 9679 or \u25cf in the Arial family
Contents.DrawText(ArialNormal, 9.0, 1.1, 0.85, "PdfFileWriter \u25cf PDF File Writer C# Class Library \u25cf Author: Uzi Granot");
// draw web link to the article
Contents.DrawWebLink(Page, ArialNormal, 9.0, 7.4, 0.85, TextJustify.Right, DrawStyle.Underline, Color.Blue, "Click to view article",
"http://www.codeproject.com/Articles/570682/PDF-File-Writer-Csharp-Class-Library-Version");
return;
}
3.5 畫兩條標題
// Draw heading
private void DrawTwoLinesOfHeading()
{
// page heading
// Arguments: Font: ArialBold, size: 36 points, Position: X = 4.25", Y = 9.5"
// Text Justify: Center (text center will be at X position)
// Stoking color: R=128, G=0, B=255 (text outline)
// Nonstroking color: R=255, G=0, B=128 (text body)
Contents.DrawText(Comic, 40.0, 4.25, 9.25, TextJustify.Center, 0.02, Color.FromArgb(128, 0, 255), Color.FromArgb(255, 0, 128), "PDF FILE WRITER");
// save graphics state
Contents.SaveGraphicsState();
// change nonstroking (fill) color to purple
Contents.SetColorNonStroking(Color.Purple);
// Draw second line of heading text
// arguments: Handwriting font, Font size 30 point, Position X=4.25", Y=9.0"
// Text Justify: Center (text center will be at X position)
Contents.DrawText(Comic, 30.0, 4.25, 8.75, TextJustify.Center, "Example");
// restore graphics sate (non stroking color will be restored to default)
Contents.RestoreGraphicsState();
return;
}
3.6 畫愉快的面孔
該DrawHappyFace
方法是從線和貝塞爾曲線繪製橢圓和構造路徑的示例。
// Draw Happy Face
private void DrawHappyFace()
{
// save graphics state
Contents.SaveGraphicsState();
// translate coordinate origin to the center of the happy face
Contents.Translate(4.25, 7.5);
// change nonstroking (fill) color to yellow
Contents.SetColorNonStroking(Color.Yellow);
// draw happy face yellow oval
Contents.DrawOval(-1.5, -1.0, 3.0, 2.0, PaintOp.Fill);
// set line width to 0.2" this is the black circle around the eye
Contents.SetLineWidth(0.2);
// eye color is white with black outline circle
Contents.SetColorNonStroking(Color.White);
Contents.SetColorStroking(Color.Black);
// draw eyes
Contents.DrawOval(-0.75, 0.0, 0.5, 0.5, PaintOp.CloseFillStroke);
Contents.DrawOval(0.25, 0.0, 0.5, 0.5, PaintOp.CloseFillStroke);
// mouth color is black
Contents.SetColorNonStroking(Color.Black);
// draw mouth by creating a path made of one line and one Bezier curve
Contents.MoveTo(-0.6, -0.4);
Contents.LineTo(0.6, -0.4);
Contents.DrawBezier(0.0, -0.8, 0, -0.8, -0.6, -0.4);
// fill the path with black color
Contents.SetPaintOp(PaintOp.Fill);
// restore graphics sate
Contents.RestoreGraphicsState();
return;
}
3.7 繪製條形碼
該DrawBarcode
方法是繪製兩個條形碼EAN-13和Code-128的示例
該DrawTwoLinesOfHeading
方法在頁面中心繪製兩個標題線。第一行是用大綱特殊效果繪製文本。
// Draw Barcode
private void DrawBarcode()
{
// save graphics state
Contents.SaveGraphicsState();
BarcodeEAN13 Barcode1 = new BarcodeEAN13("1234567890128");
Contents.DrawBarcode(1.3, 7.05, 0.012, 0.75, Barcode1, ArialNormal, 8.0);
PdfQRCode QRCode = new PdfQRCode(Document, "http://www.codeproject.com/Articles/570682/PDF-File-Writer-Csharp-Class-Library-Version", ErrorCorrection.M);
Contents.DrawQRCode(QRCode, 6.0, 6.8, 1.2);
// define a web link area coinciding with the qr code
Page.AddWebLink(6.0, 6.8, 7.2, 8.0, "http://www.codeproject.com/Articles/570682/PDF-File-Writer-Csharp-Class-Library-Version");
// restore graphics sate
Contents.RestoreGraphicsState();
return;
}
3.8 繪製與圓角的矩形和填充磚模式
該DrawBrickPattern
方法繪製具備圓角的矩形。該區域填充有磚圖案。本PdfTillingPattern
類是通常類定義劃分模式。該類有兩個靜態方法來建立特定模式。
SetBrickPattern
繪製磚牆圖案並SetWeavePattern
繪製織造圖案。
// Draw rectangle with rounded corners and filled with brick pattern
private void DrawBrickPattern()
{
// Define brick tilling pattern resource
// Arguments: PdfDocument class, Scale factor (0.25), Stroking color (lines between bricks), Nonstroking color (brick)
// Return value: tilling pattern resource
PdfTilingPattern BrickPattern = PdfTilingPattern.SetBrickPattern(Document, 0.25, Color.LightYellow, Color.SandyBrown);
// save graphics state
Contents.SaveGraphicsState();
// set outline width 0.04"
Contents.SetLineWidth(0.04);
// set outline color to purple
Contents.SetColorStroking(Color.Purple);
// set fill pattern to brick
Contents.SetPatternNonStroking(BrickPattern);
// draw rounded rectangle filled with brick pattern
Contents.DrawRoundedRectangle(1.1, 5.0, 1.4, 1.5, 0.2, PaintOp.CloseFillStroke);
// restore graphics sate
Contents.RestoreGraphicsState();
return;
}
3.9 繪製圖像並剪切它
在Draw
我法師方法是繪製一圖象的一個例子。該PdfFileWriter
存儲在支持的全部圖像文件的支持圖紙圖片Bitmap
類和Metafile
類。在ImageFormat
類定義全部圖像類型。JPEG圖像文件類型是PDF文件的本機圖像格式。若是PdfImage
使用JPEG文件調用構造函數,程序將該文件按原樣複製到PDF文件中。若是你調用PdfImage
任何其餘類型的圖像文件的構造函數,程序將其轉換爲JPEG文件。爲了保持PDF文件的大小盡量小,確保您的圖像文件分辨率不是不合理的高。
在PdfImage
類加載圖像和計算能夠適合用戶座標給定的圖像大小和保留原始寬高比最大尺寸。在繪製圖像以前,咱們建立一個橢圓形剪切路徑以剪切圖像。
// Draw image and clip it
private void DrawImage()
{
// define local image resources
// resolution 96 pixels per inch, image quality 50%
PdfImage Image1 = new PdfImage(Document, "TestImage.jpg", 96.0, 50);
// save graphics state
Contents.SaveGraphicsState();
// translate coordinate origin to the center of the picture
Contents.Translate(2.6, 5.0);
// adjust image size and preserve aspect ratio
ImageSizePos NewSize = Image1.ImageSizePosition(1.75, 1.5, ContentAlignment.MiddleCenter);
// clipping path
Contents.DrawOval(NewSize.DeltaX, NewSize.DeltaY, NewSize.Width, NewSize.Height, PaintOp.ClipPathEor);
// draw image
Contents.DrawImage(Image1, NewSize.DeltaX, NewSize.DeltaY, NewSize.Width, NewSize.Height);
// restore graphics state
Contents.RestoreGraphicsState();
return;
}
3.10 繪製心
該DrawHeart
方法經過定義中心線的兩端來顯示心形。類的DrawHeart
方法PdfContents
是繪製造成路徑的兩個對稱貝塞爾曲線的特殊狀況。
// Draw heart
private void DrawHeart()
{
// save graphics state
Contents.SaveGraphicsState();
// draw heart
// The first argument are the coordinates of the centerline of the heart shape.
// The DrawHeart is a special case of DrawDoubleBezierPath method.
Contents.SetColorNonStroking(Color.HotPink);
Contents.DrawHeart(new LineD(new PointD(4.98, 5.1), new PointD(4.98, 6.0)), PaintOp.CloseFillStroke);
// restore graphics state
Contents.RestoreGraphicsState();
return;
}
3.11 繪製餅圖
該DrawChart
方法是定義圖表並將其繪製到PDF文檔的示例。
/ Draw pie chart
private void DrawChart()
{
// save graphics state
Contents.SaveGraphicsState();
// create chart
Chart PieChart = PdfChart.CreateChart(Document, 1.8, 1.5, 300.0);
// create PdfChart object with Chart object
PdfChart PiePdfChart = new PdfChart(Document, PieChart);
// make sure we have good quality image
PieChart.AntiAliasing = AntiAliasingStyles.All;
// set colors
PieChart.BackColor = Color.FromArgb(220, 220, 255);
PieChart.Palette = ChartColorPalette.BrightPastel;
// default font
Font DefaultFont = MyPdfChart.CreateFont("Verdana", FontStyle.Regular, 0.05, FontSizeUnit.UserUnit);
Font TitleFont = MyPdfChart.CreateFont("Verdana", FontStyle.Bold, 0.07, FontSizeUnit.UserUnit);
// title (font size is 0.25 inches)
Title Title1 = new Title("Pie Chart Example", Docking.Top, TitleFont, Color.Purple);
PieChart.Titles.Add(Title1);
// legend
Legend Legend1 = new Legend();
PieChart.Legends.Add(Legend1);
Legend1.BackColor = Color.FromArgb(230, 230, 255);
Legend1.Docking = Docking.Bottom;
Legend1.Font = DefaultFont;
// chart area
ChartArea ChartArea1 = new ChartArea();
PieChart.ChartAreas.Add(ChartArea1);
// chart area background color
ChartArea1.BackColor = Color.FromArgb(255, 200, 255);
// series 1
Series Series1 = new Series();
PieChart.Series.Add(Series1);
Series1.ChartType = SeriesChartType.Pie;
Series1.Font = DefaultFont;
Series1.IsValueShownAsLabel = true;
Series1.LabelFormat = "{0} %";
// series values
Series1.Points.Add(22.0);
Series1.Points[0].LegendText = "Apple";
Series1.Points.Add(27.0);
Series1.Points[1].LegendText = "Banana";
Series1.Points.Add(33.0);
Series1.Points[2].LegendText = "Orange";
Series1.Points.Add(18.0);
Series1.Points[3].LegendText = "Grape";
Contents.DrawChart(MyPdfChart, 5.6, 5.0);
// restore graphics state
Contents.RestoreGraphicsState();
return;
}
3.12 繪製文本框
該DrawTextBox
方法是使用TextBox
類的示例。本TextBox
類格式文本,以適應列中。可使用字體的樣式和大小的真實性來繪製文本。
// Draw example of a text box
private void DrawTextBox()
{
// save graphics state
Contents.SaveGraphicsState();
// translate origin to PosX=1.1" and PosY=1.1" this is the bottom left corner of the text box example
Contents.Translate(1.1, 1.1);
// Define constants
// Box width 3.25"
// Box height is 3.65"
// Normal font size is 9.0 points.
const Double Width = 3.15;
const Double Height = 3.65;
const Double FontSize = 9.0;
// Create text box object width 3.25"
// First line indent of 0.25"
TextBox Box = new TextBox(Width, 0.25);
// add text to the text box
Box.AddText(ArialNormal, FontSize,
"This area is an example of displaying text that is too long to fit within a fixed width " +
"area. The text is displayed justified to right edge. You define a text box with the required " +
"width and first line indent. You add text to this box. The box will divide the text into " +
"lines. Each line is made of segments of text. For each segment, you define font, font " +
"size, drawing style and color. After loading all the text, the program will draw the formatted text.\n");
Box.AddText(TimesNormal, FontSize + 1.0, "Example of multiple fonts: Times New Roman, ");
Box.AddText(Comic, FontSize, "Comic Sans MS, ");
Box.AddText(ArialNormal, FontSize, "Example of regular, ");
Box.AddText(ArialBold, FontSize, "bold, ");
Box.AddText(ArialItalic, FontSize, "italic, ");
Box.AddText(ArialBoldItalic, FontSize, "bold plus italic. ");
Box.AddText(ArialNormal, FontSize - 2.0, "Arial size 7, ");
Box.AddText(ArialNormal, FontSize - 1.0, "size 8, ");
Box.AddText(ArialNormal, FontSize, "size 9, ");
Box.AddText(ArialNormal, FontSize + 1.0, "size 10. ");
Box.AddText(ArialNormal, FontSize, DrawStyle.Underline, "Underline, ");
Box.AddText(ArialNormal, FontSize, DrawStyle.Strikeout, "Strikeout. ");
Box.AddText(ArialNormal, FontSize, "Subscript H");
Box.AddText(ArialNormal, FontSize, DrawStyle.Subscript, "2");
Box.AddText(ArialNormal, FontSize, "O. Superscript A");
Box.AddText(ArialNormal, FontSize, DrawStyle.Superscript, "2");
Box.AddText(ArialNormal, FontSize, "+B");
Box.AddText(ArialNormal, FontSize, DrawStyle.Superscript, "2");
Box.AddText(ArialNormal, FontSize, "=C");
Box.AddText(ArialNormal, FontSize, DrawStyle.Superscript, "2");
Box.AddText(ArialNormal, FontSize, "\n");
Box.AddText(Comic, FontSize, Color.Red, "Some color, ");
Box.AddText(Comic, FontSize, Color.Green, "green, ");
Box.AddText(Comic, FontSize, Color.Blue, "blue, ");
Box.AddText(Comic, FontSize, Color.Orange, "orange, ");
Box.AddText(Comic, FontSize, DrawStyle.Underline, Color.Purple, "and purple.\n");
Box.AddText(ArialNormal, FontSize, "Support for non-Latin letters: ");
Box.AddText(ArialNormal, FontSize, Contents.ReverseString( "עברית"));
Box.AddText(ArialNormal, FontSize, "АБВГДЕ");
Box.AddText(ArialNormal, FontSize, "αβγδεζ");
Box.AddText(ArialNormal, FontSize, "\n");
// Draw the text box
// Text left edge is at zero (note: origin was translated to 1.1")
// The top text base line is at Height less first line ascent.
// Text drawing is limited to vertical coordinate of zero.
// First line to be drawn is line zero.
// After each line add extra 0.015".
// After each paragraph add extra 0.05"
// Stretch all lines to make smooth right edge at box width of 3.15"
// After all lines are drawn, PosY will be set to the next text line after the box's last paragraph
Double PosY = Height;
Contents.DrawText(0.0, ref PosY, 0.0, 0, 0.015, 0.05, TextBoxJustify.FitToWidth, Box);
// Create text box object width 3.25"
// No first line indent
Box = new TextBox(Width);
// Add text as before.
// No extra line spacing.
// No right edge adjustment
Box.AddText(ArialNormal, FontSize,
"In the examples above this area the text box was set for first line indent of " +
"0.25 inches. This paragraph has zero first line indent and no right justify.");
Contents.DrawText(0.0, ref PosY, 0.0, 0, 0.01, 0.05, TextBoxJustify.Left, Box);
// Create text box object width 2.75
// First line hanging indent of 0.5"
Box = new TextBox(Width - 0.5, -0.5);
// Add text
Box.AddText(ArialNormal, FontSize,
"This paragraph is set to first line hanging indent of 0.5 inches. " +
"The left margin of this paragraph is 0.5 inches.");
// Draw the text
// left edge at 0.5"
Contents.DrawText(0.5, ref PosY, 0.0, 0, 0.01, 0.05, TextBoxJustify.Left, Box);
// restore graphics state
Contents.RestoreGraphicsState();
return;
}
3.13 繪製訂單表格
該DrawBookOrderForm
方法是訂單輸入表單或發票的示例。它是數據表支持的一個示例。它演示使用的PdfTable
,PdfTableCell
以及PdfTableStyle
類。
// Draw example of order form
private void DrawBookOrderForm()
{
// Define constants to make the code readable
const Double Left = 4.35;
const Double Top = 4.65;
const Double Bottom = 1.1;
const Double Right = 7.4;
const Double FontSize = 9.0;
const Double MarginHor = 0.04;
const Double MarginVer = 0.04;
const Double Border = 0.015;
const Double Grid = 0.01;
// column widths
Double ColWidthPrice = ArialNormal.TextWidth(FontSize, "9999.99") + 2.0 * MarginHor;
Double ColWidthQty = ArialNormal.TextWidth(FontSize, "Qty") + 2.0 * MarginHor;
Double ColWidthDesc = Right - Left - Border - 3 * Grid - 2 * ColWidthPrice - ColWidthQty;
// define table
PdfTable Table = new PdfTable(Page, Contents, ArialNormal, FontSize);
Table.TableArea = new PdfRectangle(Left, Bottom, Right, Top);
Table.SetColumnWidth(new Double[] {ColWidthDesc, ColWidthPrice, ColWidthQty, ColWidthPrice});
// define all borders
Table.Borders.SetAllBorders(FrameWidth, GridWidth);
// margin
PdfRectangle Margin = new PdfRectangle(MarginHor, MarginVer);
// default header style
Table.DefaultHeaderStyle.Margin = Margin;
Table.DefaultHeaderStyle.BackgroundColor = Color.FromArgb(255, 196, 255);
Table.DefaultHeaderStyle.Alignment = ContentAlignment.MiddleRight;
// private header style for description
Table.Header[0].Style = Table.HeaderStyle;
Table.Header[0].Style.Alignment = ContentAlignment.MiddleLeft;
// table heading
Table.Header[0].Value = "Description";
Table.Header[1].Value = "Price";
Table.Header[2].Value = "Qty";
Table.Header[3].Value = "Total";
// default style
Table.DefaultCellStyle.Margin = Margin;
// description column style
Table.Cell[0].Style = Table.CellStyle;
Table.Cell[0].Style.MultiLineText = true;
// qty column style
Table.Cell[2].Style = Table.CellStyle;
Table.Cell[2].Style.Alignment = ContentAlignment.BottomRight;
Table.DefaultCellStyle.Format = "#,##0.00";
Table.DefaultCellStyle.Alignment = ContentAlignment.BottomRight;
Contents.DrawText(ArialBold, FontSize, 0.5 * (Left + Right), Top + MarginVer + Table.DefaultCellStyle.FontDescent,
TextJustify.Center, DrawStyle.Normal, Color.Purple, "Example of PdfTable support (new for 1.10.0)");
// reset order total
Double Total = 0;
// loop for all items in the order
// Order class is a atabase simulation for this example
foreach(Order Book in Order.OrderList)
{
Table.Cell[0].Value = Book.Title + ". By: " + Book.Authors;
Table.Cell[1].Value = Book.Price;
Table.Cell[2].Value = Book.Qty;
Table.Cell[3].Value = Book.Total;
Table.DrawRow();
// accumulate total
Total += Book.Total;
}
Table.Close();
// save graphics state
Contents.SaveGraphicsState();
// form line width 0.01"
Contents.SetLineWidth(FrameWidth);
Contents.SetLineCap(PdfLineCap.Square);
// draw total before tax
Double[] ColumnPosition = Table.ColumnPosition;
Double TotalDesc = ColumnPosition[3] - MarginHor;
Double TotalValue = ColumnPosition[4] - MarginHor;
Double PosY = Table.RowTopPosition - 2.0 * MarginVer - Table.DefaultCellStyle.FontAscent;
Contents.DrawText(ArialNormal, FontSize, TotalDesc, PosY, TextJustify.Right, "Total before tax");
Contents.DrawText(ArialNormal, FontSize, TotalValue, PosY, TextJustify.Right, Total.ToString("#.00"));
// draw tax (Ontario Canada HST)
PosY -= Table.DefaultCellStyle.FontLineSpacing;
Contents.DrawText(ArialNormal, FontSize, TotalDesc, PosY, TextJustify.Right, "Tax (13%)");
Double Tax = Math.Round(0.13 * Total, 2, MidpointRounding.AwayFromZero);
Contents.DrawText(ArialNormal, FontSize, TotalValue, PosY, TextJustify.Right, Tax.ToString("#.00"));
// draw total line
PosY -= Table.DefaultCellStyle.FontDescent + 0.5 * MarginVer;
Contents.DrawLine(ColumnPosition[3], PosY, ColumnPosition[4], PosY);
// draw final total
PosY -= Table.DefaultCellStyle.FontAscent + 0.5 * MarginVer;
Contents.DrawText(ArialNormal, FontSize, TotalDesc, PosY, TextJustify.Right, "Total payable");
Total += Tax;
Contents.DrawText(ArialNormal, FontSize, TotalValue, PosY, TextJustify.Right, Total.ToString("#.00"));
PosY -= Table.DefaultCellStyle.FontDescent + MarginVer;
Contents.DrawLine(ColumnPosition[0], Table.RowTopPosition, ColumnPosition[0], PosY);
Contents.DrawLine(ColumnPosition[0], PosY, ColumnPosition[4], PosY);
Contents.DrawLine(ColumnPosition[4], Table.RowTopPosition, ColumnPosition[4], PosY);
// restore graphics state
Contents.RestoreGraphicsState();
return;
}
4. 參考文獻
- Adobe PDF文件規範文檔可從Adobe網站得到:「PDF參考,第六版,Adobe便攜式文檔格式版本1.7,2006年11月」。
- 有關OpenType字體規範的信息能夠在Microsoft Typography - OpenType Specification找到。
- 「PDF文件分析器與C#解析類」一文中提供了與PDF Deflate壓縮類匹配的解壓縮類的源。
- 壓縮和解壓縮類的原始源代碼取自Uzi Granot在CodeProject.com網站上發表的「使用C#壓縮/解壓縮類處理標準ZIP文件」一文。
5. 其餘開源軟件由這個做者
- Android Color Selector for Programmers是Google Play上的免費應用程式。
- Google Play應用內結算演示應用本文是Google Play應用內結算版本3的一個示例。
6. 歷史
- 2013/04/01:版本1.0原始版本。
- 2013/04/09:版本1.1支持除句點以外的小數分隔符的國家/地區。
- 2013/07/21:版本1.2原始版本支持的圖像資源只有jpeg文件格式。版本1.2支持Bitmap類可接受的全部圖像文件。請參閱ImageFormat類。程序測試與:Bmp,Gif,圖標,Jpeg,Png和Tiff。參見上面的2.3節和3.8節。
- 2014/02/07:版本1.3修正PdfContents.DrawBezierNoP2(PointD P1,PointD P3)的錯誤。
- 2014/03/01:1.4版改進了對字符替換的支持。改進對圖像包含的支持。一些修復與PdfXObject相關。
- 2014/05/05:版本1.5不使用字體的條形碼支持。包括四個條形碼:Code-128,Code-39,UPC-A和EAN-13。參見第2.5節和第3.7節。
- 2014/07/09:版本1.6(1)建立文件後,CreateFile方法將PdfDocument重置爲初始條件。(2)PdfFont對象正確地釋放非託管代碼資源。
- 2014/08/25:版本1.7支持文檔加密,網絡連接和QR碼。
- 2014/09/12:版本1.8支持書籤。
- 2014/10/06:版本1.9支持製圖,PrintDocument和圖像元文件。
- 2014/10/12:版本1.9.1修正爲ChartExample。解析除句點以外的具備小數分隔符的區域中的數字字段。
- 2014/12/02:1.10.0版本支持數據表。添加源代碼文檔。增長每一個文檔的最大圖像數量。
- 2015/01/12:版本1.11.0支持視頻,聲音和附件文件。添加對Interleave 2 of 5條碼的支持。
- 2015/04/13:版本1.12.0支持從新排序頁面和加強數據表邊框線支持。
- 2015/05/05:1.13.0版本PDF文檔輸出到流。PDF表插入分頁符。圖像質量加強。支持標準128(RC4)加密。
- 2015/06/08:1.14.0版支持PDF表中的長文本塊或TextBox。
- 2015/06/09:版本1.14.1一行改成PdfTableStyle類的複製方法。
- 2015/06/17:版本1.15.0文檔信息字典。PdfImage重寫。其餘圖像保存選項。
- 2015/06/18:版本1.15.1從解決方案資源管理器中刪除未使用的源。
- 2015/07/27:版本1.16.0 Unicode支持。提交頁面方法。
- 2015/08/07:版本1.16.1。修正小(<0.0001)實數轉換爲字符串。
- 2015/09/01:版本1.16.2。修復未定義的字符。所選字體不支持使用的字符。
- 2015/09/22:版本1.16.3。PdfTable構造函數使用當前頁面大小來計算默認表區域矩形。當PdfTable啓動新頁面時,從上一頁獲取頁面類型和方向。
- 2015/09/30:Version 1.16.4一導致用IDisposable接口釋放非託管資源。
- 2016/01/26:版本1.17.0 WPF圖形,透明度,顏色混合,橢圓弧和二次貝塞爾曲線。
- 2016/02/29:Version 1.17.1當第一列標題是TextBox時,PdfTable將正確顯示標題。
- 2016/03/22:版本1.17.2 PdfInfo PDF文檔屬性將正確顯示。
- 2016/04/14:版本1.17.3修正了將非整數字體大小在將小數分隔符定義爲非句點(逗號)的區域中的問題。
- 2016/05/24:版本1.18.0命名目的地和PdfFont資源的建立。
- 2016/06/02:版本1.18.1從新申請1.17.3修復。
- 2016/06/13:版本1.19.0文檔連接。命名目標的更改。交互功能支持TextBox和PdfTable。
- 2016/07/27:版本1.19.1 Fix:AddLocationMarker修復了具備小數分隔符而不是句點的區域。
7. 執照