I ended up following @vicenteherrera's approach, with some tweaks (that are possibly bootstrap 3 specific).
Basically; we can't break trs, or tds because they're not block-level elements. So we embed divs into each, and apply our page-break-* rules against the div. Secondly; we add some padding to the top of each of these divs, to compensate for any styling artifacts.
<style> @media print { /* avoid cutting tr's in half */ th div, td div { margin-top:-8px; padding-top:8px; page-break-inside:avoid; } } </style> <script> $(document).ready(function(){ // Wrap each tr and td's content within a div // (todo: add logic so we only do this when printing) $("table tbody th, table tbody td").wrapInner("<div></div>"); }) </script>
The margin and padding adjustments were necessary to offset some kind of jitter that was being introduced (by my guess - from bootstrap). I'm not sure that I'm presenting any new solution from the other answers to this question, but I figure maybe this will help someone.
<thead>to your table with the following cssthead {display: table-header-group; }so as to print the table-header on all subsequent pages (useful for loooooong data tables).