Printing Table in ASP.NET MVC

I had a task today to create a quick and dirty way to print tabular data using ASP.NET MVC.  Business goal was to enable printing of search results, where only portion of the results was displayed to user, one page at a time.  So, I knew I had to make a server call, then show some friendly version of the results to the user and add some sort of Print button to the results page.  There was also no problem with showing the data in a popup instead of navigating to the print page.  So, let’s break down the solution.

 

At a high level my design was as follows.

  • Make server call to build a partial view with tabular data and print link
  • Push results into a new browser window.

Let’s look at the code now.

First, let’s look at the partial view.  I want to utilize the power of Razor syntax to make my life easier.  I also wanted to embed a rudimentary style sheet to at least color alternate rows.

@model List<MvcAppPrintTables.Models.MyModel>
@{
    var rowCounter = 0;
}
<style>
    .table {
        width: 100%;
        border: 1px solid gray;
    }

    .table td {
        padding: 2px;
    }


    .table-row-1 td, .table-row-1 th {
        background: lightgray;
        border: 0 solid lightgray;
    }

    .table-row-2 td, .table-row-2 th, thead {
        background: white;
        border: 0 solid white;
    }

    .tableHeaderRow {
        font-weight: bold;
        border: 1px solid lightgray;
    }

    .column1 {
        width: 15%;
    }

    .column2 {
        width: 15%;
    }


</style>

<style>
    /* suppress link for printing */
    @@media only print {
        a {
            display: none;
        }
    }
</style>
<a href="#" onclick="window.print(); return false;">Print</a>
<table class="table">
    <thead>
        <tr>
            <td class="tableHeaderRow column1">
                First Name
            </td>
            <td class="tableHeaderRow column2">
                Last Name
            </td>

        </tr>
    </thead>
    <tbody>

        @{
            foreach (var item in Model)
            {
                var className = "table-row-1";
                if (rowCounter % 2 == 0)
                {
                    className = "table-row-2";
                }
            <tr class="@className">
                <td>
                    @item.FirstName
                </td>
                <td>
                    @item.LastName
                </td>


            </tr>
                    rowCounter++;
            }
        }
    </tbody>
</table>
<a href="#" onclick="window.print(); return false;">Print</a>

Let’s break the code above down a bit.  First portion contains style sheet, providing bold font for header rows as well as two row styles – one for even, one for odd rows.  Then I am looping through the model I passed in – list of item, using row counter as style trigger.  Then I embed anchor tag and call print function of the browser.  I know, JavaScript is required, for this, but frankly nobody writes web apps that do not require JavaScript anymore.

Now, the controller code is uber simple.

    public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Print()
        {
            var model = new List<MyModel>();
            model.Add(new MyModel { FirstName = "John", LastName = "Doe" });
            model.Add(new MyModel { FirstName = "Jane", LastName = "Doe" });
            return PartialView(model);
        }
    }

I ma faking the data, but you could make server side call to get it of course.

And the last part is processing the results.  Here I am just using jQuery.

var myApp;
myApp = (function (app) {
    $('#printTable').click(function () {
       myApp.print();
    });

    app.print = function () {
        $.ajax({
            url: 'Home/Print',
            success: function (data) {
                if (myApp.arePopupsBlocked()) {
                    alert('Please allow popups.');
                }
                var printWindow = window.open();
                if (printWindow) {
                    $(printWindow.document.body).html(data);

                } else {
                    alert('Please allow popups.');
                }
            },
            error: function () {
                alert('Error');
            }
        });
    };

    app.arePopupsBlocked = function () {
        var aWindow = window.open(null, "", "width=1,height=1");
        try {
            aWindow.close();
            return false;
        } catch (e) {
            return true;
        }
    };
    return app;
})(window.myApp || {})

I am creating reusable myApp object with a couple of functions. Second one checks for blocked popups.  First one actually makes server call to get my partial view (HTML), then creates new window and injects my partial view into that window.  There are many other ways to do the same thing.  For example I could open a window with a URL pointing to the same Print method of my controller, but I would need to return View instead of partial view.  I find my solution though simple and illustrative of a couple of things you can do with ‘loose’ HTML in a web app.

You can download the sample app here.

Thanks.

Enjoy.

3 Comments

  1. Pingback: Printing Table in ASP.NET MVC | Sergey Barskiy's Blog | Latest News India, World & Business News

Leave a Reply

Your email address will not be published. Required fields are marked *