Печать таблицы HTML со многими столбцами/строками с использованием макета CSS?

Я хочу напечатать большую таблицу (настолько большую, что ее строки составляют около 3 листов бумаги) из HTML. Если возможно, CSS должен быть достаточным для компоновки, и решение должно работать с разными браузерами.

В настоящее время я определяю следующие правила стиля:

table { page-break-inside:auto; }
tr    { page-break-inside:auto; }

Когда я проверяю элементы DOM, например. в Firefox 33.0.2 (в OS X) я вижу, что правила распознаются, но затем, когда я смотрю на предварительный просмотр (File | Print | PDF | Open PDF в Preview), все столбцы, которые не подходят для первого страница отключена, т.е. я получаю 1 страницу печатного выхода вместо 3. Я также попытался использовать Internet Explorer 11 и 10 для того же эффекта.

Итак, как я могу компоновать большие HTML-таблицы (в конечном итоге большие как по столбцам строки) для печати с помощью CSS?

Бонусный вопрос: если компоненты стиля разрыва страницы действительно применимы только к элементам уровня блока, как указано в этом предыдущем ответе, помогло бы мне построить таблицу от div вместо td при нацеливании на выход печати?

UPDATE

Вот пример, который я только что пробовал на JSFiddle. (У меня нет учетной записи, поэтому FWIK я не могу предоставить прямую ссылку.)

HTML:

<body>
<table>
<tr>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_0</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_1</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_2</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_3</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_4</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_5</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_6</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_7</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_8</td>
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_9</td>
</tr>
</table>
</body>

CSS

table { page-break-inside:auto; }
td    { border:1px solid lightgray; }
tr    { page-break-inside:auto; }

Если я попытаюсь распечатать эту таблицу (например, применив этот кадр | Print Frame... | PDF | Открыть PDF в Preview to JSFiddle Результат в Firefox 33.1 для OS X и для формата и ориентации бумаги A4/Portrait) я получить одну страницу вывода. Все столбцы, кроме первого и второго, обрезаются.

Ответ 1

Вам абсолютно необходимо отойти от стола, если вам нужна читаемая вертикальная печать на странице. Таблицы отлично подходят для отображения на странице при табличных данных, но не являются жизнеспособным решением для печати, поскольку они не учитывают поток.

Есть плагины (например, здесь, здесь нет, аффилированность - только результат Google), который сделает это автоматически для вас, но вот пример. Когда вы используете это, убедитесь, что @media print указан соответствующим образом. Чтобы протестировать локально, вы можете изменить это на @media screen.

Это не отображает перечисленные правила @page, но они отображаются с помощью предварительного просмотра печати. ​​

Надеюсь, что это поможет:

Скрипт для печати на портрете

HTML

<section class="table">
  <div class="row">
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_0</div>
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_1</div>
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_2</div>
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_3</div>
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_4</div>
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_5</div>
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_6</div>
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_7</div>
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_8</div>
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_9</div>
  </div>
</section>

CSS

@media print {
    @page {
      margin: 2.5cm;   
    }
    div.row > div {
      display: inline-block;  
      border: solid 1px #ccc;
      margin: 0.2cm;
    }
    div.row {
      display: block;
    }
}


.table {
    display: table;
    border-spacing: 2px;
}
.row {
    display: table-row;
}
.row > div {
    display: table-cell;
    border: solid 1px #ccc;
    padding: 2px;
}

Изменить - Печать по горизонтали на нескольких страницах:

Хорошо, так что это, вероятно, гораздо менее распространенный случай использования, и мы должны делать с ним что-то смешное - так справедливое предупреждение. Я попытаюсь объяснить это шаг за шагом, как это загадочно и неприятно.

Скрипт для печати в ландшафте здесь!

CSS

@media print {
    @page {
      margin: 0;
    }
    body {
        height: 100%;
        width: 100%;
    }
    div.row > div {
      display: inline-block;  
      border: solid 1px #ccc;
      margin: 0.1cm;
      font-size: 1rem;
    }
    div.row {
      display: block;
      margin: solid 2px black;
      margin: 0.2cm 1cm;
      font-size: 0;
      white-space: nowrap;
    }
    .table {
        transform: translate(8.5in, -100%) rotate(90deg);
        transform-origin: bottom left;
        display: block;
    }
}

Это часть, которая имеет значение, поскольку она устанавливает ваши директивы печати. Большинство из них - это материал, который мы видели в оригинале (с некоторыми настройками, когда я играл с ним).

Часть, о которой мы заботимся, здесь:

 .table {
     transform: translate(8.5in, -100%) rotate(90deg);
     transform-origin: bottom left;
     display: block;
 }

То, что мы делаем, это нанести все это на свою сторону, а затем сместить его туда, где мы ожидаем. translate(8.5in, -100%) сообщает браузеру - сдвиньте этот элемент на 8,5 дюйма (ширина стандартной бумажной бумаги в США) вправо, а затем сдвиньте его на 100% от его высоты (отрицательный указывает вверх, а не вниз). Мы сдвигаем его вправо на 8,5 дюйма, чтобы он отображался в верхней части страницы при повороте. Мы сдвигаем его вверх по своей расчетной высоте, чтобы у нас не было уродливого зазора слева от таблицы, когда происходит поворот.

Затем мы проинструктируем его, что мы хотим, чтобы все эти вычисления выполнялись относительно bottom left нормального положения элемента в потоке документа. Это заставляет этот сумасшедший длинный стол поворачиваться вправо, устанавливая свойство left. Свойство bottom важно, потому что мы вращаем его по часовой стрелке на четверть оборота, и если бы мы сделали это сверху, это было бы со страницы слева. Этот четвертый ход описан в следующей части инструкции transform: rotate(90deg);

Voila. Вещь печатается на нескольких страницах.

Перед тем, как вы спросите: Нет. Невозможно предотвратить разрыв страницы внутри элемента, о котором я знаю. Я знаю, что это неприятно, уродливо и все это мусор, но мы можем работать только с инструментами, которые нам даны.

Обновление Firefox подтверждено: Firefox 33.1 on Mac

Ответ 2

page-break-inside: auto; - это стиль по умолчанию, поэтому, если у вас нет правила, устанавливающего их по-другому, эти правила ничего не сделают.

Если ваша таблица не разбивается на несколько страниц, это, скорее всего, потому, что вы добавили какое-то другое правило, которое предотвращает его - моя догадка overflow: hidden.

В первую очередь вам нужно удалить все стили и посмотреть, печатает ли это на нескольких страницах. Если да, начните добавлять свои стили назад (правило по правилу или, если необходимо, по очереди), чтобы найти проблему.

Ответ 3

Если вы хотите заставить разрывать страницу, вы должны использовать page-break-before или page-break-after. Вы должны знать, что стилизованный элемент должен содержать непустой элемент уровня блока и что он не может быть абсолютно позиционирован. Однако это довольно противоречиво для элементов таблиц. Что приводит нас к вашему последнему вопросу: да, было бы более целесообразно строить ваши таблицы с помощью divs.

Однако, учитывая то, что вы хотите достичь (печать больших горизонтальных таблиц), вы должны знать, что попытка поместить 3 страницы в 1 не может работать, так как ваш контент не будет доступен для чтения. На самом деле единственной лучшей практикой будет использование вертикальной компоновки вместо (только для печати или для веб-страниц и для печати).