Как создать программу для печати текста

Создание документа для печати. Элементы управления PrintDocument , PageSetupDialog , PrintDialog , PrintPreviewDialog

В данной теме продемонстрированы средства печати документов для программ, написанных по шаблону Windows Forms на языке программирования C#.

Поиск на других ресурсах:

Теоретические сведения

Для обеспечения печати, в .NET Framework реализованы специальные классы, базовыми из которых есть:

  • PrintDocument – представляет класс, объект которого посылает данные на принтер;
  • PageSetupDialog – представляет диалоговое окно, которое позволяет пользователю изменять настройки страницы для печати (внутренние поля, ориентация печати, и т.п.);
  • PrintDialog – представляет диалоговое окно, которое позволяет пользователю выбирать принтер и прочие настройки принтера, такие как количество копий, ориентация страницы и т.п.;
  • PrintPreviewDialog – представляет диалоговое окно, которое показывает пользователю предыдущий просмотр документа в том виде как он будет отображен при печати.

Условие задачи

Разработать приложение типа Windows Forms, который распечатывает информацию содержащуюся в элементе управления RichTextBox . Приложение должно содержать команды:

Лучшее приложение для печати текста в слепую : RapidTyping 5

  • печать документа;
  • предварительный просмотр документа;
  • настройка страниц в документе.

В программе использовать элементы управления PrintDocument , PageSetupDialog , PrintDialog , PrintPreviewDialog .

Выполнение

1. Создать проект

После создания проекта создается пустая форма. Класс формы называется Form1 .

2. Разработка формы. Размещение элементов управления на форме

Разработать главную форму программы как изображено на рисунке 1.

C#. Windows Forms. Программа печати документа. Главная форма

Рисунок 1. Главная форма программы

На форме нужно разместить следующие элементы управления:

  • элемент управления типа Label . Создается экземпляр с именем label1 ;
  • три элемента управления типа Button . Будут созданы экземпляры с именами button1 , button2 , button3 ;
  • элемент управления типа RichTextBox . Создается экземпляр с именем richTextBox1 ;
  • элемент управления типа PrintDocument . Создается экземпляр с именем printDocument1 . Этот элемент управления представляет документ, который будет распечатан;
  • элемент управления типа PageSetupDialog . Создается экземпляр с именем pageSetupDialog1 ;
  • элемент управления типа PrintDialog . Создается экземпляр с именем printDialog1 ;
  • элемент управления типа PrintPreviewDialog . Создается экземпляр с именем printPreviewDialog1 .

Размещение элементов управления PageSetupDialog , PrintDialog , PrintDocument , PrintPreviewDialog изображено на рисунке 2.

C#. Windows Forms. Элементы управления PageSetupDialog, PrintDialog, PrintDocument, PrintPreviewDialog

Word (Ворд) для начинающих – чайников. Шаг 1

Рисунок 2. Элементы управления PageSetupDialog , PrintDialog , PrintDocument , PrintPreviewDialog

3. Настройка базовых визуальных элементов управления на форме

На этом этапе нужно настроить свойства элементов управления формы следующим образом:
– в элементе управления Form1 свойство Text = «Print document» ;
– в label1 свойство Text = «Specified text:» ( label1.Text = «Specified text:» );
– button1.Text = «Page Setup» ;
– button2.Text = «Print» ;
– button3.Text = «Print Preview» .

После настройки форма будет иметь вид, как изображено на рисунке 1.

4. Настройка элементов управления PageSetupDialog , PrintDialog , PrintPreviewDialog , PrintDocument

Следующим шагом нужно связать элементы управления pageSetupDialog1 , printDialog1 , printPreviewDialog1 с документом printDocument1 . Для этого используется свойство Document . Настройки выглядят следующим образом:
– pageSetupDialog1.Document = printDocument1 (рисунок 3);
– printDialog1.Document = printDocument1 ;
– printPreviewDialog1.Document = printDocument1 ;
– printDialog1.AllowSomePages = True . Это свойство разрешает или запрещает кнопку настройки страницы в окне печати.

C#. Windows Forms. Элемент управления pageSetupDialog1. Свойство Document = printDocument1

Рисунок 3. Элемент управления pageSetupDialog1 . Свойство Document = printDocument1

5. Ввод дополнительных переменных в класс формы

Согласно условию задачи, нужно распечатать текст, который набран в элементе управления richTextBox1 . При печати нужно сохранять номер строки в richTextBox1 , которая на данный момент печатается. Для обеспечения этого в класс формы Form1 вводится дополнительная переменная counter .
Также вводится переменная curPage , определяющая страницу, которая печатается на данный момент.

Фрагмент текста класса формы Form1 следующий

. public partial class Form1 : Form < // Количество выделенных строк: // 0 int counter = 0; // сквозной номер строки в массиве строк, которые выводятся int curPage; // текущая страница . > .

6. Программирование обработчиков событий
6.1. Основные события, обеспечивающие печать документа

Если вызывается команда печати на принтер или предварительного просмотра документа, то в работу вступают обработчики событий класса PrintDocument . С помощью событий класса PrintDocument можно руководить печатью документа.
Перечень возможных событий класса PrintDocument следующий:

  • BeginPrint – это событие возникает перед самым началом печати документа. В обработчик этого события целесообразно вписывать код инициализации внутренних переменных, которые руководят печатью документа;
  • PrintPage – возникает один раз при печати каждой страницы. Например, если печатается 5 страниц, то это событие возникнет 5 раз;
  • EndPrint – возникает, после печати документа;
  • QueryPageSetting – возникает прежде чем каждая страница должна быть напечатана. Перехват этого события полезен в случаях, когда нужно изменить настройки конкретной печатаемой страницы.
Читайте также:
Программа которая записывает скайп
6.2. Программирование обработчика события BeginPrint компонента printDocument1

Первым программируется событие BeginPrint элемента управления printDocument1 . Чтобы получить обработчик этого события, нужно выбрать элемент управления printDocument1 и в перечне событий выбрать событие BeginPrint (двойной клик мышкой).
В нашем случае, в обработчике события BeginPrint нужно реализовать инициализацию переменных counter и curPage

// Начало печати private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e) < // Перед началом печати переменные-счетчики // установить в начальные значения counter = 0; curPage = 1; >

6.3. Программирование обработчика события PrintPage компонента printDocument1

Основной программный код, выполняющий вывод на принтер, реализован в обработчике события PrintPage . Текст обработчика следующий:

// Обработчик события PrintPage — здесь нужно программировать печать private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) < // Создать шрифт myFont Font myFont = new Font(«Arial», 14, FontStyle.Regular, GraphicsUnit.Pixel); string curLine; // текущая выводимая строка // Отступы внутри страницы float leftMargin = e.MarginBounds.Left; // отступы слева в документе float topMargin = e.MarginBounds.Top; // отступы сверху в документе float yPos = 0; // текущая позиция Y для вывода строки int nPages; // количество страниц int nLines; // максимально-возможное количество строк на странице int i; // номер текущей строки для вывода на странице // Вычислить максимально возможное количество строк на странице nLines = (int)(e.MarginBounds.Height / myFont.GetHeight(e.Graphics)); // Вычислить количество страниц для печати nPages = (richTextBox1.Lines.Length — 1) / nLines + 1; // Цикл печати/вывода одной страницы i = 0; while ((i < nLines) (counter < richTextBox1.Lines.Length)) < // Взять строку для вывода из richTextBox1 curLine = richTextBox1.Lines[counter]; // Вычислить текущую позицию по оси Y yPos = topMargin + i * myFont.GetHeight(e.Graphics); // Вывести строку в документ e.Graphics.DrawString(curLine, myFont, Brushes.Blue, leftMargin, yPos, new StringFormat()); counter++; i++; > // Если весь текст не помещается на 1 страницу, то // нужно добавить дополнительную страницу для печати e.HasMorePages = false; if (curPage < nPages) < curPage++; e.HasMorePages = true; >>

Объясним некоторые фрагменты кода в обработчике.
На основе размера заданного шрифта myFont и высоты страницы e.MarginBounds.Height определяется количество строк nLines , которые может вместить одна страница. Страниц может быть несколько. Номер текущей страницы определяется во внутренний переменной curPage , которая была описана в п. 5.
На основании количества строк на странице nLines и общего количества выводимых строк richTextBox1.Lines.Length , вычисляется общее количество страниц печати nPages .

В цикле while фигурирует два счетчика: счетчик страницы i и счетчик сквозной строки вывода counter (см. п. 5). Как только один из счетчиков принимает свое максимальное значение, происходит выход из цикла.

Также, в цикле в переменной yPos формируется координата y вывода текста по формуле. Вывод строки с текстом осуществляется с помощью метода

// Вывести строку в документ e.Graphics.DrawString(curLine, myFont, Brushes.Blue, leftMargin, yPos, new StringFormat());

  • e – экземпляр типа PrintPageEventArgs , обеспечивающий необходимые данные для события PrintPage . С помощью этих данных можно управлять печатью документа;
  • e.Graphics – класс, который предназначен для рисования на странице. Кроме текста можно выводить любые графические примитивы;
  • e.Graphics.DrawString() – метод, который выводит определенную строку ( curLine ) в определенной позиции ( leftMargin , yPos ). Строка выводится шрифтом myFont и цветом Brushes.Blue .

В методе e.Graphics.DrawString() задается необязательный формат вывода типа StringFormat с помощью вызова

new StringFormat()

После цикла while происходит определение того, нужно ли генерировать следующую страницу

. // сначала принять, что следующая страница не генерируется e.HasMorePages = false; if (curPage < nPages) // Если это не последняя страница < curPage++; e.HasMorePages = true; // тогда нужно сгенерировать новую страницу > .

Значение e.HasMorePages отвечает за генерирование следующей страницы. Если e.HasMorePages=true то следующая страница генерируется. В противном случае следующая страница не генерируется, а это значит, что текущая страница есть последней. В программе происходит сравнение значения curPage (текущая страница) с общим количеством страниц nPages . Если значения curPage и nPages равны, то e.HasMorePages становится равным false и печать (просмотр) страниц прекращается.

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

6.4. Программирование обработчика события клика на кнопке «Page Setup»

Если пользователь сделал клик на кнопке «Page Setup» , то должно открыться окно настройки параметров страницы.

// Команда Page Setup private void button1_Click(object sender, EventArgs e) < pageSetupDialog1.ShowDialog(); // отобразить окно >

6.5. Программирование обработчика события клика на кнопке «Print»

Непосредственно печать документа осуществляется с помощью метода Print() , который вызывается из экземпляра printDocument1 . Предварительно выводится диалоговое окно печати.

// Команда Print() private void button2_Click(object sender, EventArgs e) < if (printDialog1.ShowDialog() == DialogResult.OK) printDocument1.Print(); >

Читайте также:
Программа сетевое окружение это
6.6. Программирование обработчика события клика на кнопке «PrintPreview»

// Команда PrintPreviewDialog() private void button3_Click(object sender, EventArgs e)

7. Запуск программы на выполнение

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

Связанные темы

Источник: www.bestprog.net

Автоматизируем печать документов с помощью Python

Каждый день, я готовлю однообразные документы, в которых нужно печатать страницы — одинаково (однообразно):
1 (ую) и 2 (ую) страницы, двойной печатью по длинному краю;
3 (ью) и 4 (ую) по короткому краю (эти листы горизонтальные);
5 (ую) страницу отдельно (только 1 лист).

Каждый день, из раза в раз, нужно было настраивать диапазон для печатати. И в один момент (спустя 3 дня) мне это надоело и я решил написать программу, с помощью которой можно будет распечатать этот документ — одним нажатием мыши.

Спойлер — мне удалось. Но пришлось поискать информацию, а информации на русском не очень много, поэтому искал преимущественно в английских источниках.

Задача

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

Решение

Из Word в PDF

Для начала преобразуем Word документы в отдельные PDF файлы, для этого устанавливаем следящую библиотеку:

pip install docx2pdf

Систематизация страниц

Далее устанавливаем библиотеку для редактирования страниц в pdf:

pip install pikepdf

Пишем функцию для чтения и систематизации документа на под файлы т.к используя эту библиотеку, мы будет удалять из нашего файла страницы, то пишем функцию для более удобного удаления:

def del_pages(pdf, arr, num_pages=16): max = arr[1] min = arr[0] — 1 del pdf.pages[max:num_pages] del pdf.pages[0:min] return pdf # -1 для того, чтобы вы писали с 1 страницы, а не с 0. #В начале это не мешает, но если страниц 20, то в конце можно запутаться.

Сохранение новых файлов

Печать документов

Для работы с принтерами установим следующую библиотеку

pip install pywin32

Далее пишем функцию для печати т.к мы ее будем вызывать для каждого нужного файла

import win32print import win32api #print_pdf (входной pdf, режим печати, какой принтер) #режим печати: 1 — односторонняя, 2 двойная по длинному краю, 3 — по короткому def print_pdf(input_pdf, mode=2, printer=1): # тут мои принтеры, для своихузнаем имя дефолтного принтера через метод win32print.GetDefaultPrinter() if int(printer) == 2: name = «\\buh\BUH DCP-L5500DN series (копия 1)» #win32print.GetDefaultPrinter() elif int(printer) == 1: name = «Brother DCP-L2540DN series Printer» #win32print.GetDefaultPrinter() try: # Устанавливаем дефолтный принтер win32print.SetDefaultPrinterW(name) win32print.SetDefaultPrinter(name) finally: # Если не получилось или получилось -> устанавливаем этот принтер стандартом name = win32print.GetDefaultPrinter() # оставляем без изменений ## тут нужные права на использование принтеров printdefaults = ## начинаем работу с принтером («открываем» его) handle = win32print.OpenPrinter(name, printdefaults) ## Если изменить level на другое число, то не сработает level = 2 ## Получаем значения принтера attributes = win32print.GetPrinter(handle, level) ## Настройка двухсторонней печати attributes[‘pDevMode’].Duplex = mode #flip over 3 — это короткий 2 — это длинный край ## Передаем нужные значения в принтер win32print.SetPrinter(handle, level, attributes, 0) win32print.GetPrinter(handle, level)[‘pDevMode’].Duplex ## Предупреждаем принтер о старте печати win32print.StartDocPrinter(handle, 1, [input_pdf, None, «raw»]) ## 2 в начале для открытия pdf и его сворачивания, для открытия без сворачивания поменяйте на 1 win32api.ShellExecute(2,’print’, input_pdf,’.’,’/manualstoprint’,0) ## «Закрываем» принтер win32print.ClosePrinter(handle) ## Меняем стандартный принтер на часто используемый win32print.SetDefaultPrinterW(«Brother DCP-L2540DN series Printer») win32print.SetDefaultPrinter(«Brother DCP-L2540DN series Printer») # Пример inputs_print = next(os.walk(outdir))[2] # Берем все файлы в папке outdir # Печатаем документы for input_print in inputs_print: # Путь до файла, который нужно расспечатать path_print = outdir + input_print # Если в названии файла есть ‘Экзаменационный’, то печатаем по короткому краю if ‘Экзаменационный’ in input_print: print_pdf(path_print, 3, num) else: print_pdf(path_print, 2, num)
Полный код c переделкой на работу с php сервером:

Вывод

Сразу про минусы:
принтеры не всегда меняются (т.е печатает, только, 1 принтер), разбираюсь почему.

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

Прощу, раскритиковать мой говнокод и поделится своим мнением о автоматизации печати (как вы это делали) или была ли моя статья полезно для вас

Это моя первая статья, поэтому давайте пожестче

P.S Документы генерирую на php форме с php сервера, на котором запускаю Python скрипт, с помощью php формы

Источник: habr.com

Читайте также:
Как написать путь к программе

Windows GDI, C++: печать текста

В одном из недавних постов я описал, как можно сделать печать из консольной программы с помощью функций из набора Windows API (в том числе с помощью функций Windows GDI):
https://ilyachalov.livejournal.com/107298.html

(Использовался компилятор среды «Visual Studio Community 2017».)

Для, собственно, вывода текста я остановился там на функции TextOut:

BOOL OK = TextOutW(printerDC, 100, 100, str, wcslen(str));

Это самый простой вариант. Но у него есть недостаток: он выводит на указанное устройство (в нашем случае — виртуальный принтер Microsoft XPS Document Writer) только одну строку. Если строка выходит за пределы листа, то автоматического переноса не произойдет, а символ новой строки ‘n’ или endl эта функция игнорирует. Например (картинка кликабельна):

Более интересный вариант — функция DrawText:

RECT rc = < 100, 100, GetDeviceCaps(printerDC, HORZRES) — 100, GetDeviceCaps(printerDC, VERTRES) — 100 >; int OK = DrawTextW(printerDC, str, wcslen(str),

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

Функция GetDeviceCaps возвращает разнообразную информацию об устройстве. В данном случае — максимальную ширину (в пикселях) и максимальную высоту (в пикселях) листа. Далее из этих величин отнимаем по 100 пикселей, чтобы между прямоугольником с текстом и краем листа был зазор из 100 пикселей.

Значением DT_WORDBREAK указываем функции DrawText, что необходимо обеспечить автоматический перенос слов, если строка достигает правого края листа.

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

Пример (тот же текст, что и в случае функции TextOut, картинка кликабельна):

Всё бы хорошо, однако, можно заметить (см. картинку в 100 % размере), что некоторые буквы наезжают друг на друга или, наоборот, слишком далеко отходят друг от друга в некоторых словах. А некоторые знаки препинания вообще уезжают со своих мест довольно далеко.

Очевидно, требуется программная настройка шрифта. Ранее я не упоминал о шрифте, надеясь, что нормально подойдет шрифт по умолчанию. Поэтому и в программе шрифт не определял.

Кстати, чтобы определить, что за шрифт используется по умолчанию и какие у него настройки, можно применить, например, функции GetTextFace (для получения названия семейства шрифтов) и GetTextMetrics (для получения настроек шрифта). С их помощью я определил, что в моем случае для шрифта по умолчанию название семейства шрифтов — «Arial», а высота его символов — 100 пикселей.

Тут важно заметить, что размеры пикселей (точек) экрана и листа бумаги отличаются. Например, в моем случае (виртуальный принтер Microsoft XPS Document Writer) функция GetDeviceCaps вернула для листа A4 размер в пикселях 4961 × 7016 (600 × 600 dpi или просто 600 dpi). Разрешение экрана у меня 1280 × 1024 в пикселях (размеры экрана 15,2 × 11,4 в дюймах, диагональ 19 дюймов, то есть примерно 84,21 × 89,82 ppi). Получается, что в моем случае размер пикселя на листе бумаги гораздо меньше размера пикселя на экране (примерно в 7 раз).

Определить шрифт нужно до отправки текста на печать. Следующим образом можно определить шрифт с установками, аналогичными шрифту, который у меня выбирается по умолчанию:

HFONT hFont = CreateFontW(100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L»Arial»); SelectObject(printerDC, hFont);

Функция CreateFont возвращает дескриптор с настройками шрифта, а функция SelectObject подбирает по этим настройкам наиболее подходящий шрифт из имеющихся в операционной системе. Видно, что у шрифта может быть много настроек, но достаточно указать только высоту символов в пикселях (100) и название семейства шрифтов (Arial), а значения остальных аргументов можно определить нулем.

На странице функции CreateFont на сайте компании Microsoft рекомендуется следующая формула для преобразования размера шрифта в пунктах (1 пункт равен 1/72 дюйма) к размеру шрифта в пикселях устройства:

fHeight = -MulDiv(РазмерВПунктах, GetDeviceCaps(hDC, LOGPIXELSY), 72);

Я прикинул по вышеуказанной картинке, что размер шрифта по умолчанию в пунктах примерно равен 11. Тогда пишем следующее:

HFONT hFont; int fHeight = -MulDiv(11, GetDeviceCaps(printerDC, LOGPIXELSY), 72); hFont = CreateFontW(fHeight, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L»Arial»); SelectObject(printerDC, hFont);

Упомянутая выше формула расчета высоты символов в пикселях дала значение 103 (а не 100, как для шрифта по умолчанию). При этом текст на печать вывелся без упомянутых выше артефактов (картинка кликабельна):

Источник: ilyachalov.livejournal.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru