Search code examples
asp.net-mvcprintingbatch-processingrotativa

Batch print multiple orders with a given template from MVC


I have a simple 'administration system' written in MVC. It is for an eCommerce business and I'm looking for the best way to physically print a batch of orders with a single button press.

The system is MVC5 at the moment and uses an ASP.Net Web API to get order data. My API can easily return the orders I want. But my question is how to print that collection of orders with a specific template.

So far I'm using an MVC view and the excellent Rotativa to convert my view to PDF an allow me to print. This is only really good for a single order, but my requirement is one button that prints all orders (within a given filter).

Any ideas on how to approach this?


Solution

  • I figured out how to do this using Rotativa.

    Rotativa respects the CSS 'page-break-after' attribute so using this, you can add a page break in your view whenever you want to page break, thus allowing the use of a foreach loop in your view to enumerate orders.

    In my controller I have the following action that responds to the 'print all' button. The height and width measurements relate to the standard size for an A4 sheet of paper:

        public ActionResult Print()
        {
            var r =  new ActionAsPdf("IndexPrintFormat") 
            { 
                FileName = DateTime.Now.ToShortDateString()+".pdf",
                PageSize = Rotativa.Options.Size.A4,
                PageOrientation = Rotativa.Options.Orientation.Portrait,
                PageHeight = 297,
                PageWidth = 210
            };
    
            return r;
        }
    

    My controller also has an action called "IndexPrintFormat" which renders the actual view i want printed. This enumerates a collection of orders and after each order adds a P which uses the following CSS

            .breakhere {
            display: block;
            clear: both;
            page-break-after: always;
        }
    

    The P is as follows

    <p class="breakhere"></p>
    

    The whole 'IndexPrintFormat' view is roughly as follows (cut down here to get to the point of the post)

    @model <MyViewModelPathGoesHere>
    
    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <style>
            .breakhere {
                display: block;
                clear: both;
                page-break-after: always;
            }
        </style>
    </head>
    <body>
        @foreach (var order in Model.Orders)
        {
            <div>
    //display whatever you want to display for each order here
    
    //This causes a new page in the PDF
                <p class="breakhere"></p>
            </div>
        }
    </body>
    </html>
    

    I hope this helps someone in the future! :)