我需要从我的Windows Phone应用程序生成PDF。
遗憾的是没有标准的免费的PDF生成库在Windows Phone上运行。 我不得不自己生成PDF,通过直接写入到文件格式。 这竟然是真的很容易! 源代码是在这个文档的底部,并在此链接:
为什么要在移动电话上生成PDF
举个例子,我想生成一个PDF,将其上传到用户的SkyDrive的帐户,让用户发送一封电子邮件,一个“分享”链接。 这就是当你点击“分享”按钮,微软自己的PDF阅读器应用程序的工作原理。
其他人认为,一个电话没有业务生成PDF文件,因为它是这样一个代价高昂的操作,你应该不是您的文档上传到您的PDF生成的Web服务器。 这是错误的。 PDF生成,至少对于种报告我产生(两页的非流动文本),是一种非常廉价的手术。 我敢打赌,它的成本更多的电池上传+下载,而不是生成PDF文档。
iTextSharp
http://itextpdf.com/ (AGPL许可证,或者您也可以购买商业许可,可在的NuGet)
iTextSharp的不能在Windows Phone的工作 ,
PDFSharp
http://www.pdfsharp.net/ (MIT许可证,可在的NuGet)
PDFSharp不能在Windows Phone上的工作
PDFJet
http://www.pdfjet.com/os/edition.html (BSD许可证;对不能提供的NuGet)
PDFJet不能在Windows Phone上的工作
PDFClown
http://pdfclown.wordpress.com/ (LGPL许可证;对不能提供的NuGet)
PDFClown不能在Windows Phone上的工作
自己写的PDF文件格式
http://acroeng.adobe.com/wp/?page_id=321 (PDF的文件格式的文档,我用的是1.2版本的PDF规范的)
下面的代码在Windows Phone上的运行得很好,PDF文件格式非常简单,如果你想要做的就是创建简单的报告-用文字,图表&C。 我们需要的是为展示如何创建PDF文件。 因此,这里是我的示例代码! 请注意,我使用一个额外功能“ENC”,这意味着非ASCII从Unicode(在.NET中使用)到WinAnsiEncoding(我选择要使用的PDF编码) - 完整的源代码是从顶部的链接下载这篇文章的。
Private Async Sub Button1_Click(sender As Object , e As RoutedEventArgs ) HandlesButton1.Click
Dim file = Await ApplicationData .Current.LocalFolder.CreateFileAsync( "a.pdf" , Windows.Storage. CreationCollisionOption .ReplaceExisting)
Using stream = Await System.IO. WindowsRuntimeStorageExtensions.OpenStreamForWriteAsync(file),
writer As New IO. StreamWriter (stream, Text. Encoding .UTF8)
Dim xrefs As New List ( Of Long )()
' PDF-HEADER
writer.WriteLine( "%PDF-1.2" )
' PDF-BODY. Convention is to start with a 4-byte binary comment
' so everyone recognizes the pdf as binary. Then the file has
' a load of numbered objects, #1..#7 in this case
writer.Write( "%" ) : writer.Flush()
stream.Write({&HC7, &HEC, &H8F, &HA2}, 0, 4) : stream.Flush()
writer.WriteLine( "" )
' #1: catalog - the overall container of the entire PDF
writer.Flush() : stream.Flush() : xrefs.Add(stream.Position)
writer.WriteLine( "1 0 obj" )
writer.WriteLine( "<<" )
writer.WriteLine( " /Type /Catalog" )
writer.WriteLine( " /Pages 2 0 R" )
writer.WriteLine( ">>" )
writer.WriteLine( "endobj" )
' #2: page-list - we have only one child page
writer.Flush() : stream.Flush() : xrefs.Add(stream.Position)
writer.WriteLine( "2 0 obj" )
writer.WriteLine( "<<" )
writer.WriteLine( " /Type /Pages" )
writer.WriteLine( " /Kids [3 0 R]" )
writer.WriteLine( " /Count 1" )
writer.WriteLine( ">>" )
writer.WriteLine( "endobj" )
' #3: page - this is our page. We specify size, font resources, and the contents
writer.Flush() : stream.Flush() : xrefs.Add(stream.Position)
writer.WriteLine( "3 0 obj" )
writer.WriteLine( "<<" )
writer.WriteLine( " /Type /Page" )
writer.WriteLine( " /Parent 2 0 R" )
writer.WriteLine( " /MediaBox [0 0 612 792]" ) ' Default userspace units: 72/inch, origin at bottom left
writer.WriteLine( " /Resources" )
writer.WriteLine( " <<" )
writer.WriteLine( " /ProcSet [/PDF/Text]" ) ' This PDF uses only the Text ability
writer.WriteLine( " /Font" )
writer.WriteLine( " <<" )
writer.WriteLine( " /F0 4 0 R" ) ' I will define three fonts, #4, #5 and #6
writer.WriteLine( " /F1 5 0 R" )
writer.WriteLine( " /F2 6 0 R" )
writer.WriteLine( " >>" )
writer.WriteLine( " >>" )
writer.WriteLine( " /Contents 7 0 R" )
writer.WriteLine( ">>" )
writer.WriteLine( "endobj" )
' #4, #5, #6: three font resources, all using fonts that are built into all PDF-viewers
' We're going to use WinAnsi character encoding, defined below.
writer.Flush() : stream.Flush() : xrefs.Add(stream.Position)
writer.WriteLine( "4 0 obj" )
writer.WriteLine( "<<" )
writer.WriteLine( " /Type /Font" )
writer.WriteLine( " /Subtype /Type1" )
writer.WriteLine( " /Encoding /WinAnsiEncoding" )
writer.WriteLine( " /BaseFont /Times-Roman" )
writer.WriteLine( ">>" )
writer.Flush() : stream.Flush() : xrefs.Add(stream.Position)
writer.WriteLine( "5 0 obj" )
writer.WriteLine( "<<" )
writer.WriteLine( " /Type /Font" )
writer.WriteLine( " /Subtype /Type1" )
writer.WriteLine( " /Encoding /WinAnsiEncoding" )
writer.WriteLine( " /BaseFont /Times-Bold" )
writer.WriteLine( ">>" )
writer.Flush() : stream.Flush() : xrefs.Add(stream.Position)
writer.WriteLine( "6 0 obj" )
writer.WriteLine( "<<" )
writer.WriteLine( " /Type /Font" )
writer.WriteLine( " /Subtype /Type1" )
writer.WriteLine( " /Encoding /WinAnsiEncoding" )
writer.WriteLine( " /BaseFont /Times-Italic" )
writer.WriteLine( ">>" )
' #7: contents of page. This is written in postscript, fully described in
' chapter 8 of the PDF 1.2 reference manual.
writer.Flush() : stream.Flush() : xrefs.Add(stream.Position)
Dim sb As New Text. StringBuilder
sb.AppendLine( "BT" ) ' BT = begin text object, with text-units the same as userspace-units
sb.AppendLine( "/F0 40 Tf" ) ' Tf = start using the named font "F0" with size "40"
sb.AppendLine( "40 TL" ) ' TL = set line height to "40"
sb.AppendLine( "230.0 400.0 Td" ) ' Td = position text point at coordinates "230.0", "400.0"
sb.AppendLine( "(Hello all) '" ) ' Apostrophe = print the text, and advance to the next line
sb.AppendLine( "/F2 20 Tf" ) '
sb.AppendLine( "20 TL" ) '
sb.AppendLine( "0.0 0.2 1.0 rg" ) ' rg = set fill color to RGB("0.0", "0.2", "1.0")
sb.AppendLine( "(ol" & enc( "é" ) & ") '" )
sb.AppendLine( "ET" ) '
'
writer.WriteLine( "7 0 obj" )
writer.WriteLine( "<<" )
writer.WriteLine( " /Length " & sb.Length)
writer.WriteLine( ">>" )
writer.WriteLine( "stream" )
writer.Write(sb.ToString())
writer.WriteLine( "endstream" )
writer.WriteLine( "endobj" )
' PDF-XREFS. This part of the PDF is an index table into every object #1..#7
' that we defined.
writer.Flush() : stream.Flush() : Dim xref_pos = stream.Position
writer.WriteLine( "xref" )
writer.WriteLine( "1 " & xrefs.Count)
For Each xref In xrefs
writer.WriteLine( "{0:0000000000} {1:00000} n" , xref, 0)
Next
' PDF-TRAILER. Every PDF ends with this trailer.
writer.WriteLine( "trailer" )
writer.WriteLine( "<<" )
writer.WriteLine( " /Size " & xrefs.Count)
writer.WriteLine( " /Root 1 0 R" )
writer.WriteLine( ">>" )
writer.WriteLine( "startxref" )
writer.WriteLine(xref_pos)
writer.WriteLine( "%%EOF" )
End Using
Await Windows.System. Launcher .LaunchFileAsync(file)
End Sub