Отчёты в Интернете
Во всём, что работает не с Интернетом, есть разные инструменты создания отчётов. От программиста требуется описать отчёт. А этот инструмент отчёт (с данными) сформирует, даст возможность посмотреть или вывеет на печать.
В конструкторе отчёта, также как и на форме – окне, рисуется заголовок, расставляются столбцы колонки, задаётся какие и где должны быть итоги. Ещё, естественно, задаётся источник информации, т.е где в базе брать данные отчёта. Это всю можно назвать описанием отчета, которое создаёт программист.
Созданному описанию отчёту передаются данные. Он их расставляет в нужные места и сам выводит, строка за строкой, всю таблицу.
Разбивка на страницы, рисование заголовка на шапки на каждой странице, отслеживание того чтобы итоги выводились под данными а не отдельно на следующей странице – всем этим занимается этот стандартный программный инструмент.
В Интернете такого нет. Может, конечно, что-то есть, но я не знаю.
Инструмента нет, а печать нужна. Решения могут быть разные. Одно из них – вывод данных в Excel. Т.е данные передаются в запускающийся Excel, там их можно менять как угодно. Оттуда же можно и печатать. Вариант хорош гибкостью, но для постоянной печати, когда надо просто что-то типовое постоянно засовывать в принтер это просто очень долго, потому что куча лишних действий.
Следующий вариант – генерирование html-страницы с отчётом. В Интернете нет никаких проблем с печатью. Любой браузер загонит страницу в принтер. Надо только чтобы была белая страница, на которой просто обычная таблица с данными.
У меня делается именно так. Единственно, что это тоже можно делать по-разному, с разным качеством. Приличный документ должен прилично выглядеть. Т.е если он длинный, то иметь шапку на каждом листе и т.д. А вот так браузер печатать уже не будет. Он погонит в принтер всё подряд. Если устраивает вариант – скрепить это всё скрепкой, то можно обойтись и так.
А если не устраивает, то надо генерировать таблицу уже разбитую на страницы. В Windows это делать сложнее чем в DOS. В DOS было точно известно, сколько букв помещается на страницу по ширине и высоте. Здесь же шрифты разные, размеры разные и т.д. Из-за всех этих сложностей фактически DOS-овский вариант печати вручную (строка за строкой) нигде больше не используется.
Сложно-то оно сложно, но приноровиться можно. Для этого достаточно выбрать какой-то шрифт и, например, ограничиться несколькими его размерами. Я уже рассказываю, как у меня это сделано. Можно, конечно, сделать иначе, может более трудоёмко, но с большими возможностями. А дальше надо, выводя информацию строка за строкой, накапливать суммарную высоту распечатанного и переходить к печати следующей страницы, если эта сумма приблизилась в высоте листа.
Чтобы это всё было проще делать не думая об этих цифрах, я сделала объект для печати (prinpage.cs). Вот в нем внутри, какие-то цифры в пикселях:
Насколько помню это высота и ширина страницы и высота букв (обычных и жирных) трёх основных размеров – 8, 10,11. Такие вещи пишутся как раз для того чтобы больше это всё никогда не видеть а только вызывать функции печати (чтобы оно там внутри само всё это отслеживало).
Часть этих функций:
Mm_to_px – перевод миллиметров в пиксели. Это что-то совсем внутреннее. Где-то зачем-то и это потребовалось.
PrintPageNum. Вывод номера страницы. Судя по тому что номер (цифра) не передаётся, плюсуется это номер внутри объекта, а при печати отчёта достаточно просто запустить эту функцию фактически без параметров. И номер будет выведен нужный и шрифт там будет уже задан какой-то стандартный. Обычно такие вещи как этот шрифт тоже хранятся во внутренних переменных объекта. Если очень надо, то их можно поменять. А если не надо, то будет распечатано как-то стандартно. Объекты нужны чтобы проще и меньше писать в тех самых стандартных случаях.
PrintTd – вывод ячейки таблицы с заданным форматированием.
Вот такое:
prn.PrintTd(“123 456.87”, 50, "R");
будет преобразовано в примерно такой текст:
<td width=50px align=”Right”>123 456.87</td>
Ни то чтобы конкретно это сильно отличалось по количеству букв, но писать так проще. Думать меньше. Я думаю о том, что мне надо (это и формулирую). А внутренний механизм мне не нужен, потому он от меня, по возможности, скрыт. В том числе внутри суммируется та самая высоту распечатанного.
Очень удачно расположены рядом две функции:
После печати каждой строки я просто проверяю, не нужен ли переход на следующую страницу
if NeedBreak() {}
В данном случае от меня скрыта информация, что стандартная высота страница 973 px.
А если нужен переход, то пишу так:
strTable +=prn.EndTable();
prn .PrintTable(div1, strTable);
prn.PageBreak(div1);
prn.PrintTitle(div1);
prn.PrintPageNum(div1, intHeadW);
prn.PrintHead(div1);
strTable = prn.StartTable();
strTable += strPrev;
prn.IncHeight(dblPrevHeight);
Тут можно даже ничего не комментировать. Всё понятно по названиям.
Endtable – дорисовать в хвост таблицы её окончание <\/table>. Printtable – вывести таблицу на страницу. Pagebreak – вывод на страницу последовательности символов "<br style='page-break-after:always;' />", которая заставит принтер выплюнуть страницу и.т.д.
Есть ситуация, которую эта штука не отслеживает. Итоги должны быть под данными. Обычные инструменты если видят, что данные влезут а итоги нет, переносят на следующую страницу и строки тоже. Мне было лень придумывать, как это сделать. Ситуация не очень частая. Мне было проще дать пользователям возможность менять высоту страницы. Т.е то самое 973, которое по умолчанию, на чуть меньшее. Тогда вся эта штука будет печатать страницу чуть короче. Значит на следующей странице окажется хотя бы она строка с информацией. По виду незаметно, как будто поля чуть больше поставлены а неподобающего вида у документа нету.
Но они этим, по-моему, ни разу не пользовались.
Результат примерно так выглядит:
|