Chandni Sirwani
Chandni Sirwani

Reputation: 77

PDF Generation In Windows app 8.1

I am trying to generate the pdf file in windows app 8.1 (not windows phone) c#, I have tried with using the postscript because i didn't find any free package to generate the pdf. If there is please let me know.

Here is the sample code which i have tried using postscript,

 var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("MyFirstPdf.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.7");
                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");

                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");

                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");

                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(">>");

                writer.Flush();
                stream.Flush();
                xrefs.Add(stream.Position);
                System.Text.StringBuilder sb = new System.Text.StringBuilder();

                //Lables  
                sb.AppendLine("BT");
                sb.AppendLine("/F0 15 Tf");
                sb.AppendLine("20 TL");
                sb.AppendLine("30.0 760.0 Td");
                sb.AppendLine("(testlist demo1)' Tj");
                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");  //added  
                writer.WriteLine("    156 0 0 272 100 200 cm");  
                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. 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");
            }

Yes, It works fine and generate the pdf which works properly in microsoft edge but while opening that same file with adobe reader it is giving blank output..

Another Solution i have tried using PDFDocument but in that also i am getting same problem.

Please Help me out. Awaiting Response.

Thanks In Advance

Upvotes: 1

Views: 134

Answers (1)

KenS
KenS

Reputation: 31139

OK There are a number of problems here. A minor point is that your file has 3 bytes of garbage binary before the file begins. Possibly this is a UTF BOM or something. PDF readers are supposed to skip that, but its worth getting it right. Opening the file with a binary editor I see it starts 0xEF 0xBB 0xBF 0x25 0x50....

Secondly the xref is incorrect:

xref
1 7
0000000020 65536 n
0000000079 00000 n
0000000149 00000 n
0000000382 00000 n
0000000489 00000 n
0000000595 00000 n
0000000703 00000 n

You are starting that cross-reference subsection from 1, you ought to start it from 0, and 0 ought to be the head of the linked list of free objects. See the PDF reference page 93 onwards. The xref should look something like:

xref
0 8
0000000000 00000 f
0000000020 00000 n
0000000079 00000 n
0000000149 00000 n
0000000382 00000 n
0000000489 00000 n
0000000595 00000 n
0000000703 00000 n

So that's 8 entries, numbered from 0 to 7, entry 0 is the head of the linked list of free entries, and so is marked as free.

Congratulations on getting the length of each entry correct, that's a fault many people fall over.

A corollary is that the /Size entry in the trailer dictionary should be 8, not 7:

trailer
<<
  /Size 8
  /Root 1 0 R
>>

The content stream (object 7) is declared as having a length of 63 bytes, whereas in fact its 115 bytes.

The content stream contains:

(testlist demo1)' Tj

removing the extraneous ' resolves that problem.

Finally (for now) you have attempted to use an XObject:

/Img1 Do

But you have not declared the XObject 'Img1' in the Resources dictionary of the page, and in fact you have not defined the XObject anywhere in the file, so that's simply not going to work.

I suspect that's enough to be going on with :-)

Upvotes: 1

Related Questions