Ответ 1
Это можно сделать с помощью обычного старого JavaScript, о чем свидетельствует приведенный ниже код.
<!DOCTYPE html>
<html>
<body>
<table class="data">
<caption><b>MY TABLE</b></caption>
<thead>
<tr>
<th>Col 1</th><th>Col 2</th>
</tr>
</thead>
<tbody>
<tr><td>1<td>1<tr><td>0<td>99<tr><td>1<td>1<tr><td>0<td>99<tr><td>1<td>1<tr><td>0<td>99
<tr><td>2<td>9<tr><td>2<td>88<tr><td>2<td>0<tr><td>2<td>88<tr><td>2<td>0<tr><td>2<td>88
<tr><td>3<td>1<tr><td>4<td>77<tr><td>3<td>1<tr><td>4<td>77<tr><td>3<td>1<tr><td>4<td>77
<tr><td>4<td>8<tr><td>6<td>66<tr><td>4<td>1<tr><td>6<td>66<tr><td>4<td>1<tr><td>6<td>66
<tr><td>5<td>1<tr><td>8<td>55<tr><td>5<td>1<tr><td>8<td>55<tr><td>5<td>1<tr><td>8<td>55
<tr><td>6<td>7<tr><td>0<td>44<tr><td>6<td>2<tr><td>0<td>44<tr><td>6<td>2<tr><td>0<td>44
<tr><td>7<td>1<tr><td>2<td>33<tr><td>7<td>1<tr><td>2<td>33<tr><td>7<td>1<tr><td>2<td>33
<tr><td>8<td>6<tr><td>4<td>22<tr><td>8<td>3<tr><td>4<td>22<tr><td>8<td>3<tr><td>4<td>22
<tr><td>9<td>1<tr><td>6<td>11<tr><td>9<td>1<tr><td>6<td>11<tr><td>9<td>1<tr><td>6<td>11
<tr><td>1<td>0<tr><td>0<td>99<tr><td>1<td>4<tr><td>0<td>99<tr><td>1<td>4<tr><td>0<td>99
<tr><td>2<td>1<tr><td>2<td>88<tr><td>2<td>1<tr><td>2<td>88<tr><td>2<td>1<tr><td>2<td>88
<tr><td>3<td>1<tr><td>4<td>77<tr><td>3<td>1<tr><td>4<td>77<tr><td>3<td>1<tr><td>4<td>77
<tr><td>4<td>5<tr><td>6<td>66<tr><td>4<td>5<tr><td>6<td>66<tr><td>4<td>5<tr><td>6<td>66
<tr><td>5<td>1<tr><td>8<td>55<tr><td>5<td>1<tr><td>8<td>55<tr><td>5<td>1<tr><td>8<td>55
<tr><td>6<td>4<tr><td>0<td>44<tr><td>6<td>6<tr><td>0<td>44<tr><td>6<td>6<tr><td>0<td>44
<tr><td>7<td>1<tr><td>2<td>33<tr><td>7<td>1<tr><td>2<td>33<tr><td>7<td>1<tr><td>2<td>33
<tr><td>8<td>3<tr><td>4<td>22<tr><td>8<td>7<tr><td>4<td>22<tr><td>8<td>7<tr><td>4<td>22
<tr><td>9<td>1<tr><td>6<td>11<tr><td>9<td>1<tr><td>6<td>11<tr><td>9<td>1<tr><td>6<td>11
<tr><td>1<td>2<tr><td>0<td>99<tr><td>1<td>8<tr><td>0<td>99<tr><td>1<td>8<tr><td>0<td>99
<tr><td>2<td>1<tr><td>2<td>88<tr><td>2<td>1<tr><td>2<td>88<tr><td>2<td>1<tr><td>2<td>88
<tr><td>3<td>0<tr><td>4<td>77<tr><td>3<td>9<tr><td>4<td>77<tr><td>3<td>9<tr><td>4<td>77
<tr><td>4<td>1<tr><td>6<td>66<tr><td>4<td>1<tr><td>6<td>66<tr><td>4<td>1<tr><td>6<td>66
<tr><td>5<td>1<tr><td>8<td>55<tr><td>5<td>0<tr><td>8<td>55<tr><td>5<td>0<tr><td>8<td>55
<tr><td>6<td>1<tr><td>0<td>44<tr><td>6<td>1<tr><td>0<td>44<tr><td>6<td>1<tr><td>0<td>44
<tr><td>7<td>0<tr><td>2<td>33<tr><td>7<td>1<tr><td>2<td>33<tr><td>7<td>1<tr><td>2<td>33
<tr><td>8<td>1<tr><td>4<td>22<tr><td>8<td>1<tr><td>4<td>22<tr><td>8<td>1<tr><td>4<td>22
<tr><td>9<td>0<tr><td>6<td>11<tr><td>9<td>2<tr><td>6<td>11<tr><td>9<td>2<tr><td>6<td>11
<tr><!--Use this row for on-screen totals if needed; otherwise, leave it empty.-->
</tbody>
</table>
</body>
</html>
<style>
@media screen {
.print {
display: none; /*Prevents print version of table from showing on screen*/
}
}
@media print {
.data {
display: none; /*Prevents screen version of table from showing in print*/
}
.print {
display: block;
}
.print > .data {
display: inline-table; /*Prevents page breaks better than page-break-inside: avoid;*/
vertical-align: top;
}
/*The following rule makes rows opaque in IE even if background colors are disabled.*/
.print.fixIE > .data > thead > tr > th:after,
.print.fixIE > .data > tbody > tr:first-child > td:after {
display: block;
border-bottom: 18pt solid white; /*Border-width = line-height*/
margin-top: -18pt; /*Negative line-height*/
margin-right: -.5em; /*Negative td padding-right*/
margin-left: -.5em; /*Negative td padding-left*/
content: "";
}
.overlap {
margin-bottom: -20pt; /*Negative row height (including borders)*/
}
}
.data {
table-layout: fixed; /*Columns must have fixed widths! Set with <col>s, if needed.*/
width: 100%;
border-spacing: 0;
white-space: nowrap;
font-size: 12pt;
line-height: 18pt; /*If you change this, other CSS values must also be changed!*/
border-right: 1pt solid black;
}
.data > thead > tr > th {
border-top: 1pt solid black;
border-left: 1pt solid black;
background: white;
padding: 0 .5em 0 .5em;
}
.data > tbody > tr > td {
border-top: 1pt solid black; /*If you change this, .overlap must also be changed!*/
border-left: 1pt solid black;
background: white;
padding: 0 .5em 0 .5em; /*If you change this, other CSS values must also be changed!*/
}
.data > tbody > tr:last-child > td {
border-bottom: 1pt solid black; /*If you change this, .overlap must also be changed!*/
}
.data > tbody {
text-align: right;
}
</style>
<script>
//This function takes two arguments:
//1) a reference to a table element
//2) an array of column indexes indicating which columns have numbers to be totalled.
function printSubtotals(table, columns) {
var
tbody = table.tBodies[0],
row = tbody.rows[0];
if(!row)
return;
var cellCount = row.cells.length;
if(!cellCount)
return;
var
subtotals = [],
rows = table.rows,
thead = table.tHead,
caption = table.querySelector('caption'),
colgroup = table.querySelector('colgroup'),
emptyTable = table.cloneNode(false),
emptyRow = row.cloneNode(true),
printDiv = document.createElement('div'),
overlap = document.createElement('div'),
subtotalCount = columns.length,
rowCount = rows.length - 1,
cells, subtotalCells, i, r;
if(colgroup && colgroup.parentNode === table)
emptyTable.appendChild(colgroup.cloneNode(true));
emptyTable.appendChild(tbody.cloneNode(false));
printDiv.className = /MSIE /.test(navigator.userAgent) ? 'print fixIE' : 'print';
overlap.className = 'overlap';
for(i = subtotalCount; i--; subtotals.push(0));
for(i = cellCount; i--; emptyRow.cells[i].innerHTML = '');
for(r = row.rowIndex; r < rowCount; r++) {
printDiv.appendChild(overlap.cloneNode(true));
tbody = printDiv.appendChild(emptyTable.cloneNode(true)).tBodies[0];
cells = tbody.appendChild(rows[r].cloneNode(true)).cells;
subtotalCells = tbody.appendChild(emptyRow.cloneNode(true)).cells;
for(i = subtotalCount; i--;) {
subtotals[i] += parseFloat(cells[columns[i]].innerHTML);
subtotalCells[columns[i]].innerHTML = '<b>Total: ' + subtotals[i] + '</b>';
}
}
printDiv.removeChild(printDiv.children[0]);
tbody = printDiv.children[0].tBodies[0];
if(caption && caption.parentNode === table)
tbody.parentNode.insertBefore(caption.cloneNode(true), tbody);
if(thead)
tbody.parentNode.insertBefore(thead.cloneNode(true), tbody);
table.parentNode.insertBefore(printDiv, table);
}
printSubtotals(document.querySelector('.data'), [0,1]);
</script>
Что делает функция Javascript, это создать версию только для печати таблицы, в которой каждая строка имеет скрытую промежуточную промежуточную строку, прикрепленную к ней. Строка промежуточных итогов закрывается следующей строкой, поэтому она видна только в том случае, если следующая строка попадает на следующую страницу или последняя строка в таблице. Это должно работать практически в любом браузере независимо от формата бумаги. Это может показаться неэффективным, но воспринимаемый выигрыш производительности ничтожно мал, поскольку таблица печати не отображается при загрузке страницы. Тем не менее, я бы не рекомендовал эту технику для таблиц со многими тысячами строк.
Обратите внимание, что приведенный выше код является просто доказательством концепции и, как таковой, не является особенно надежным. Несколько вещей, которые, как я знаю, нарушат это:
- пустые ячейки в столбцах данных
- нечисловые значения в столбцах данных
- многострочный контент в ячейках tbody
- изменение количества ячеек в строках tbody (например, некоторые из них имеют colspans, а другие нет)
- разрешение содержимого ячейки определяет ширину столбца
- изменение высоты линии или ширины границы без изменения других связанных значений CSS
Некоторые из этих вещей выполняются с правильными изменениями в JavaScript и CSS.