简体   繁体   中英

iTextSharp print multiple pages

I have MVC application where I am able to make a call and print one record on PDF. What I need to do now is to print all the records in a model into a PDF file with one record per page. My record is being formatted via a HTML view and the Razor engine. How do I accomplish this?

This is my code to actually create the PDF -

private void CreatePDF(string HTMLData, string fileName)
{
    StringReader reader = new StringReader(HTMLData);

    //Create PDF document 
    Document doc = new Document(PageSize.A4, 36, 36, 36, 36);
    HTMLWorker parser = new HTMLWorker(doc);

    StyleSheet styles = new StyleSheet();
    styles.LoadTagStyle(HtmlTags.TABLE, HtmlTags.SIZE, "6pt");
    styles.LoadTagStyle(HtmlTags.H3, HtmlTags.SIZE, "10pt");
    styles.LoadTagStyle(HtmlTags.H5, HtmlTags.SIZE, "6pt");

    parser.SetStyleSheet(styles);

    PdfWriter.GetInstance(doc, new FileStream(fileName, FileMode.Create));
    doc.Open();
    try
    {
        //Parse Html and dump the result in PDF file
        parser.Parse(reader);
    }
    catch (Exception ex)
    {
        //Display parser errors in PDF. 
        Paragraph paragraph = new Paragraph("Error!" + ex.Message);
        Chunk text = paragraph.Chunks[0] as Chunk;
        if (text != null)
        {
            text.Font.Color = BaseColor.RED;
        }
        doc.Add(paragraph);
    }
    finally
    {
        doc.Close();
    }
}

This is the calling function which produces a single PDF with one record -

    var oOrder = _unitOfWork.OrderRepository.Get.Where(m => m.Id == id).FirstOrDefault();

    if (oOrder != null)
    {
        OrderViewModel vm = new OrderViewModel() { Order = oOrder, Customer = _unitOfWork.CustomerRepository.Find(oOrder.CustomerId) };
        GetEntityViewModelLists(vm);
        string receipt = RenderRazorViewToString(ControllerContext, "_Receipt", vm);

        var fileName = "Order Receipt_" + oOrder.Id + ".pdf";
        var filepath = System.IO.Path.GetTempPath();
        var filePath = filepath + fileName;

        CreatePDF(receipt, filePath);

        return new FileStreamResult(new FileStream(filePath, FileMode.Open, FileAccess.Read), "application/pdf"); 

The simplest change would probably be to change the first parameter of CreatePDF() from a string into a collection of strings and just loop over that. (I didn't test this code but it should be pretty accurate.)

private void CreatePDF(IList<string> HTMLData, string fileName) {
    //Create PDF document 
    Document doc = new Document(PageSize.A4, 36, 36, 36, 36);
    HTMLWorker parser = new HTMLWorker(doc);

    StyleSheet styles = new StyleSheet();
    styles.LoadTagStyle(HtmlTags.TABLE, HtmlTags.SIZE, "6pt");
    styles.LoadTagStyle(HtmlTags.H3, HtmlTags.SIZE, "10pt");
    styles.LoadTagStyle(HtmlTags.H5, HtmlTags.SIZE, "6pt");

    parser.SetStyleSheet(styles);

    PdfWriter.GetInstance(doc, new FileStream(fileName, FileMode.Create));
    doc.Open();

    //Try/Catch removed
    foreach (var s in HTMLData) {
        StringReader reader = new StringReader(s);
        parser.Parse(reader);
        doc.NewPage();
    }

    doc.Close();
}

You could optionally overload your original method, too, if you don't want to change the other callers.

private void CreatePDF(string HTMLData, string fileName) {
    CreatePDF(new string[] { HTMLData }, fileName);
}

Then instead of getting a single order you would get all of them and loop over those

//I just made up a method but use whatever returns all of them
var oOrders = _unitOfWork.OrderRepository.GetAll();

//Create our collection of receipts
var receipts = new List<string>();
foreach (var oOrder in oOrders) {
    OrderViewModel vm = new OrderViewModel() { Order = oOrder, Customer = _unitOfWork.CustomerRepository.Find(oOrder.CustomerId) };
    GetEntityViewModelLists(vm);
    receipts.Add(RenderRazorViewToString(ControllerContext, "_Receipt", vm));
}

CreatePDF(receipts, filePath);

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