简体   繁体   中英

Aspx to PDF iTextSharp usage

I have this code which I merged and modified for my needs. But I still can't make it work as I need. The first part that I made, it generates PDF with an option from aspx page chosen. Second, I need to have the background over the page, so I added next code, but now it generates just the second code and not the PDF. And im not able to merge those codes together.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

public partial class CreatePDFFromScratch : System.Web.UI.Page
{
    protected void btnCreatePDF_Click(object sender, EventArgs e)
    {
        // Create a Document object
          var document = new Document(iTextSharp.text.PageSize.LETTER.Rotate(), 0f, 0f, 0f, 0f);

        // Create a new PdfWrite object, writing the output to a MemoryStream
        var output = new MemoryStream();
        var writer = PdfWriter.GetInstance(document, output);

        // Open the Document for writing
        document.Open();

        // First, create our fonts..
        var titleFont = FontFactory.GetFont("Arial", 18, Font.BOLD);
        var subTitleFont = FontFactory.GetFont("Arial", 14, Font.BOLD);
        var boldTableFont = FontFactory.GetFont("Arial", 12, Font.BOLD);
        var endingMessageFont = FontFactory.GetFont("Arial", 10, Font.ITALIC);
        var bodyFont = FontFactory.GetFont("Arial", 12, Font.NORMAL);

        // Add the "Northwind Traders Receipt" title
        document.Add(new Paragraph("Northwind Traders Receipt", titleFont));

        // Now add the "Thank you for shopping at Northwind Traders. Your order details are below." message
        document.Add(new Paragraph("Thank you for shopping at Northwind Traders. Your order details are below.", bodyFont));
        document.Add(Chunk.NEWLINE);

        // Add the "Order Information" subtitle
        document.Add(new Paragraph("Order Information", subTitleFont));

        // Create the Order Information table 
        var orderInfoTable = new PdfPTable(2);
        orderInfoTable.HorizontalAlignment = 0;
        orderInfoTable.SpacingBefore = 10;
        orderInfoTable.SpacingAfter = 10;
        orderInfoTable.DefaultCell.Border = 0;

        orderInfoTable.SetWidths(new int[] { 1, 4 });
        orderInfoTable.AddCell(new Phrase("Order:", boldTableFont));
        orderInfoTable.AddCell(txtOrderID.Text);
        orderInfoTable.AddCell(new Phrase("Price:", boldTableFont));
        orderInfoTable.AddCell(Convert.ToDecimal(txtTotalPrice.Text).ToString("c"));

        document.Add(orderInfoTable);

        // Add the "Items In Your Order" subtitle
        document.Add(new Paragraph("Items In Your Order", subTitleFont));

        // Create the Order Details table
        var orderDetailsTable = new PdfPTable(3);
        orderDetailsTable.HorizontalAlignment = 0;
        orderDetailsTable.SpacingBefore = 10;
        orderDetailsTable.SpacingAfter = 35;
        orderDetailsTable.DefaultCell.Border = 0;

        orderDetailsTable.AddCell(new Phrase("Item #:", boldTableFont));
        orderDetailsTable.AddCell(new Phrase("Item Name:", boldTableFont));
        orderDetailsTable.AddCell(new Phrase("Qty:", boldTableFont));

        foreach (System.Web.UI.WebControls.ListItem item in cblItemsPurchased.Items)
            if (item.Selected)
            {
                // Each CheckBoxList item has a value of ITEMNAME|ITEM#|QTY, so we split on | and pull these values out...
                var pieces = item.Value.Split("|".ToCharArray());
                orderDetailsTable.AddCell(pieces[1]);
                orderDetailsTable.AddCell(pieces[0]);
                orderDetailsTable.AddCell(pieces[2]);
            }

        document.Add(orderDetailsTable);


        // Add ending message
        var endingMessage = new Paragraph("Thank you for your business! If you have any questions about your order, please contact us at 800-555-NORTH.", endingMessageFont);
        endingMessage.SetAlignment("Center");
        document.Add(endingMessage);

        document.Close();

        Response.ContentType = "application/pdf";
        Response.AddHeader("Content-Disposition", string.Format("inline;filename=Receipt-{0}.pdf", txtOrderID.Text));

        ///create background

        Response.BinaryWrite(output.ToArray());

        Response.Cache.SetCacheability(HttpCacheability.NoCache);

    string imageFilePath = Server.MapPath(".") + "/images/1.jpg";

    iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(imageFilePath);

    Document pdfDoc = new Document(iTextSharp.text.PageSize.LETTER.Rotate(), 0, 0, 0, 0);

    jpg.ScaleToFit(790, 777);

    jpg.Alignment = iTextSharp.text.Image.UNDERLYING;

    pdfDoc.Open();

    pdfDoc.NewPage();       

    pdfDoc.Add(jpg);

    pdfDoc.Close();

    Response.Write(pdfDoc);

    Response.End();


    }
}

Thanks

I almost missed this question because it wasn't tagged as an itext question.

First let me copy/paste/adapt @mkl 's comment:

The first part of your code in which you create a document document makes sense. The second part in which you create a document pdfDoc does not. First of all, at the end of the first part you write the pdf to the response. That PDF is complete. It's finished. It's done. It's ready to send to the browser.

Why do you think anything additional written to the response thereafter might have a chance of combining with the original written data to a properly generated PDF?

Also: the second part of your code is written as if you want to create a new PDF from scratch; but didn't you want to manipulate the PDF created in the first part?

All of this is true, but it doesn't solve your problem. It only reveals your deep lack of understanding in PDF.

There are different ways to achieve what you want. I see that you want to use an image as a background of all the pages of a newly created PDF. In that case, you should create a page event, and add that image underneath all the existing content in the OnEndPage() method. This is explained in the answer to How can I add an image to all pages of my PDF?

Create a PDF as is done in the first part of your code, but introduce a page event:

// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.GetInstance(document, stream);
MyEvent event = new MyEvent();
writer.PageEvent = event;
// step 3
document.Open();
// step 4
// Add whatever content you want to add
// step 5
document.Close();

What is the MyEvent class, you might ask? Well, that's a class you create yourself like this:

protected class MyEvent : PdfPageEventHelper {

    Image image;

    public override void OnOpenDocument(PdfWriter writer, Document document) {
        image = Image.GetInstance(Server.MapPath("~/images/background.png"));
        image.SetAbsolutePosition(0, 0);
    }

    public override void OnEndPage(PdfWriter writer, Document document) {
        writer.DirectContent.AddImage(image);
    }
}

Suppose that your requirement isn't as easy as adding an image in the background, then you could use the bytes created as output to create a PdfReader instance. You could then use the PdfReader to create a PdfStamper and you can use the PdfStamper to watermark the original document. If the simple solution doesn't meet your needs, create a new question that involves PdfReader / PdfStamper and don't forget to tag that question as an iText question. (And also: please read the documentation. A lot of time was spent on the iText web site. That time was wasted if you don't consult it.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM