c#實現生成PDF的底層方法


在用uwp生成pdf的時候,發展此類類庫有限,有的也需要錢,我最后實現pdf的底層方法生成pdf,代碼如下

 private async void GeneratePdf()
 {

            var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("uwpCSharp.pdf", Windows.Storage.CreationCollisionOption.ReplaceExisting);
            using (var stream = await System.IO.WindowsRuntimeStorageExtensions.OpenStreamForWriteAsync(file))
            {
                using (var writer = new System.IO.StreamWriter(stream, System.Text.Encoding.UTF8))
                {

                    List<long> xrefs = new List<long>();
                    writer.WriteLine("%PDF-1.2");
                    writer.Write("%");
                    writer.Flush();
                    byte[] bytes = { 0, 0, 0, 0 };
                    stream.Write(bytes, 0, 4);
                    stream.Flush();
                    writer.WriteLine("");

                    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: 頁面列表 - 我們只有一頁文字  
                    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: 頁面 - 這里放文字、資源等 
                    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]");
                    // 默認的用戶空間: 72/inch  
                    writer.WriteLine("  /Resources");
                    writer.WriteLine("  <<");
                    writer.WriteLine("    /ProcSet [/PDF/Text]");
                    // 這個pdf只有文本  
                    writer.WriteLine("    /Font");
                    writer.WriteLine("    <<");
                    writer.WriteLine("      /F0 4 0 R");
                    // 定義的三種字體, #4, #5 和 #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: 三鍾字體,我們使用pdf默認字體  
                    //使用WinAnsi字符編碼,定義如下 
                    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:內容頁面。這是用postscript編寫的,  
                    // 有興趣的朋友可以查看PDF 1.2參考手冊第8章  
                    writer.Flush();
                    stream.Flush();
                    xrefs.Add(stream.Position);
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    sb.AppendLine("BT");
                    // BT =開始文本對象
                    sb.AppendLine("/F0 30 Tf");
                    // Tf = 使用文字 "F0"  定義文字大小為 "30"  
                    sb.AppendLine("30 TL");
                    // TL = 設置高度為 "30"  
                    sb.AppendLine("140.0 780.0 Td");
                    // Td = 文本坐標的位置 "140.0", "780.0"  
                    sb.AppendLine("1.0 0.0 0.6 rg");
                    // rg = 字體前景顏色設置
                    sb.AppendLine("(Microsoft Corporation India) '");
                    sb.AppendLine("ET");

                    //畫線  
                    //頂部的線
                    sb.AppendLine("BT");
                    sb.AppendLine("10 TL");
                    sb.AppendLine("50.0 730.0 Td");
                    sb.AppendLine("0.0 0.0 0.0 rg");
                    sb.AppendLine("(__________________________________)'");
                    sb.AppendLine("ET");

                    //左邊 
                    sb.AppendLine("BT");
                    sb.AppendLine("10 TL");
                    sb.AppendLine("47.0 703.0 Td");
                    sb.AppendLine("0.0 0.0 0.0 rg");
                    for (int i = 0; i <= 60; i++)
                    {
                        sb.AppendLine("(|)'");
                    }
                    sb.AppendLine("ET");

                    //中間的線 
                    sb.AppendLine("BT");
                    sb.AppendLine("10 TL");
                    sb.AppendLine("240.0 703.0 Td");
                    sb.AppendLine("0.0 0.0 0.0 rg");
                    for (int i = 0; i <= 60; i++)
                    {
                        sb.AppendLine("(|)'");
                    }
                    sb.AppendLine("ET");

                    //畫右邊的線 
                    sb.AppendLine("BT");
                    sb.AppendLine("10 TL");
                    sb.AppendLine("557.0 703.0 Td");
                    sb.AppendLine("0.0 0.0 0.0 rg");
                    for (int i = 0; i <= 60; i++)
                    {
                        sb.AppendLine("(|)'");
                    }
                    sb.AppendLine("ET");

                    //底部的線  
                    sb.AppendLine("BT");
                    sb.AppendLine("10 TL");
                    sb.AppendLine("50.0 102.0 Td");
                    sb.AppendLine("0.0 0.0 0.0 rg");
                    sb.AppendLine("(__________________________________)'");
                    sb.AppendLine("ET");

                    //文字  
                    sb.AppendLine("BT");
                    sb.AppendLine("/F0 15 Tf");
                    sb.AppendLine("20 TL");
                    sb.AppendLine("70.0 670.0 Td");
                    sb.AppendLine("0.0 0.2 1.0 rg");
                    sb.AppendLine("(Parameter1)'");
                    sb.AppendLine("ET");
                    //  
                    sb.AppendLine("BT");
                    sb.AppendLine("/F0 15 Tf");
                    sb.AppendLine("20 TL");
                    sb.AppendLine("0.0 0.0 0.0 rg");
                    sb.AppendLine("260.0 670.0 Td");
                    sb.AppendLine("(test1) '");
                    sb.AppendLine("ET");
                    //  
                    sb.AppendLine("BT");
                    sb.AppendLine("/F0 15 Tf");
                    sb.AppendLine("20 TL");
                    sb.AppendLine("0.0 0.2 1.0 rg");
                    sb.AppendLine("70.0 645.0 Td");
                    sb.AppendLine("(Parameter2)'");
                    sb.AppendLine("ET");
                    //  
                    sb.AppendLine("BT");
                    sb.AppendLine("/F0 15 Tf");
                    sb.AppendLine("20 TL");
                    sb.AppendLine("0.0 0.0 0.0 rg");
                    sb.AppendLine("260.0 645.0 Td");
                    sb.AppendLine("(test2) '");
                    sb.AppendLine("ET");
                    //  
                    sb.AppendLine("BT");
                    sb.AppendLine("/F0 15 Tf");
                    sb.AppendLine("20 TL");
                    sb.AppendLine("0.0 0.2 1.0 rg");
                    sb.AppendLine("70.0 615.0 Td");
                    sb.AppendLine("(Parameter3)'");
                    sb.AppendLine("ET");
                    //  
                    sb.AppendLine("BT");
                    sb.AppendLine("/F0 15 Tf");
                    sb.AppendLine("20 TL");
                    sb.AppendLine("260.0 615.0 Td");
                    sb.AppendLine("0.0 0.0 0.0 rg");
                    sb.AppendLine("(test3) '");
                    //  
                    //  
                    sb.AppendLine("BT");
                    sb.AppendLine("/F0 15 Tf");
                    sb.AppendLine("20 TL");
                    sb.AppendLine("0.0 0.2 1.0 rg");
                    sb.AppendLine("70.0 575.0 Td");
                    sb.AppendLine("(Parameter4)'");
                    sb.AppendLine("ET");
                    //  
                    sb.AppendLine("BT");
                    sb.AppendLine("/F0 15 Tf");
                    sb.AppendLine("20 TL");
                    sb.AppendLine("260.0 575.0 Td");
                    sb.AppendLine("0.0 0.0 0.0 rg");
                    sb.AppendLine("(test4) '");
                    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("  q");   
                    writer.WriteLine("    156 0 0 272 100 200 cm");  //[1 2 3 4 5 6 cm] translate to (5,6) and scale for 1  
                    writer.WriteLine("    /Img1 Do");
                    writer.WriteLine("  Q");
                    writer.WriteLine("endstream");
                    writer.WriteLine("endobj");


                    writer.Flush();
                    stream.Flush();
                    dynamic xref_pos = stream.Position;
                    writer.WriteLine("xref");
                    writer.WriteLine("1 " + xrefs.Count);
                    long xref = 0;
                    foreach (long xref_loopVariable in xrefs)
                    {
                        xref = xref_loopVariable;
                        writer.WriteLine("{0:0000000000} {1:00000} n", xref, 0);
                    }

                    // PDF-TRAILER. PDF以這個節點結尾.  
                    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");
                }
            }

            await Windows.System.Launcher.LaunchFileAsync(file);
        }

 


免責聲明!

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



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