Печать с помощью delphi

#delphi #delphi-2007

#delphi #delphi-2007

Вопрос:

Я сталкиваюсь с некоторыми трудностями при печати, когда я печатаю свои отчеты на физическом принтере, тексты идеально центрируются, но когда я печатаю тот же отчет на принтере PDF (например, CutePDF) или XPS document writer, левое поле становится равным 0. Между тем, когда я пытаюсь настроить поле, оно отлично работает в PDF и XPS, но физическая печать печатает страницы с некоторым дополнительным левым полем. Я не могу обнаружить эту разницу, также я пытался установить поле только для нефизической печати, но не смог этого сделать. Было бы здорово, если бы можно было установить размер поля в соответствии с выбором принтера, например, если я выберу PDF printer или XPS writer, поле будет изменено. Я использую Printer.canvas.textout(), процедуру для печати текста.

Кто-нибудь, пожалуйста, может мне помочь в этом.

Комментарии:

1. Добро пожаловать в StackOverflow. Практически невозможно, чтобы кто-либо помог вам с вашей проблемой, потому что вы не опубликовали никакого кода. Если мы не можем видеть, как вы пытаетесь печатать, мы не сможем понять, что вы делаете неправильно. Пожалуйста, помните, что мы не можем видеть ваш экран отсюда, и поэтому 100% имеющейся у нас информации — это то, что вы указали в своем вопросе. Пожалуйста, отредактируйте свой пост и предоставьте соответствующий код (вы также можете попробовать добавить несколько разрывов на абзацы в свой вопрос, чтобы сделать его более читабельным, пока вы над ним работаете). Для того чтобы мы помогли вам с вашей проблемой, вы должны помочь нам понять ее. Спасибо. 🙂

Ответ №1:

Некоторые моменты, которые стоит выделить:

  • Из Windows (и из Delphi TPrinter.Canvas ) POV, во время рисования нет такого понятия, как поля: для холста доступен весь формат бумаги — например, X = 0 будет указывать на крайнюю левую часть бумаги;
  • Существуют так называемые «аппаратные поля» или «физические поля», в зависимости от возможностей принтера: это область, недоступная для печати вокруг бумаги; то есть, если вы нарисуете что-то в этой области, это не будет закрашено — эти поля зависят от технологии и модели используемого принтера, и в некоторых случаях можно получить значения «полей» из драйвера принтера с помощью GetDeviceCaps вызовов API;
  • Но, исходя из моего эксперимента, не доверяйте этим «физическим полям», получаемым драйвером принтера — лучше (и эстетичнее) использовать некоторые программно определяемые поля, и пусть ваш пользователь изменяет их при необходимости (например, параметры «Макет страницы» в MS Word);
  • Принтеры PDF обычно являются виртуальными, поэтому у них нет никакого «физического поля»;
  • При печати PDF-документа Acrobat Reader способен «подогнать» содержимое страницы к «физическим полям» физического принтера.

Итак, вот несколько возможных решений:

  • В Acrobat Reader, если в вашем PDF-файле нет полей, нажмите «Печать», затем выберите «Поместить в область для печати» в опции «Обработка страницы / масштабирование страницы» — я предполагаю, что у вас здесь «Нет» в качестве настроек, поэтому результат усекается принтером;
  • В вашем приложении Delphi при составлении отчета установите некоторые «логические» поля (например, 1 см вокруг листа бумаги), то есть не начинайте с X = 0 и Y = 0, а с некоторыми смещениями, и пусть ширина и высота области рисования будут меньше (см., Например, как реализован наш механизм создания отчетов с открытым исходным кодом).;
  • В вашем приложении Delphi, если вы используете компонент отчета, должны быть некоторые свойства для установки полей.

Смотрите эту статью об общей печати с использованием Delphi (некоторая информация устарела, но большая часть по-прежнему точна) или правильно настройте свой механизм создания отчетов.

Комментарии:

1. большое спасибо за такое приятное объяснение. Я думаю, что то, что вы предлагали, чтобы иметь некоторое «логическое» поле по всем страницам, было бы неплохо.

2. В Delphi XE2 (по крайней мере) Printer.PageWidth равно GetDeviceCaps(DC, HorzRes) , что является шириной области страницы, пригодной для печати , т.е. меньше физической ширины бумаги.

Ответ №2:

Если вы используете TextOut (и не DrawText используете), у вас есть координаты x и y, куда вы собираетесь поместить строки, которые вам нужно распечатать. Вы можете следить за вычислениями в отладчике (или регистрировать их, если приложение запускается без присутствия отладчика). Возможно, что-то идет не так при определении координат (например, TextExtend не удается измерить текст перед центрированием, например, разрешение отличается от ожидаемого, вы получаете холст принтера с преобразованием, поэтому координаты не равны 1: 1 с пикселями.

Если вы не уверены в проблемах с координатами / шрифтом: попробуйте нарисовать несколько прямоугольников в ожидаемых координатах, чтобы исключить из уравнения все ошибки, связанные со шрифтом. Если они демонстрируют одни и те же проблемы, это проблема с координатами, если нет, то это каким-то образом проблема со шрифтом.

Как сказал Кен, мы не сможем узнать ничего больше, если вы не покажете код… так много возможностей..

Комментарии:

1. Если бы вы придержали свой ответ до тех пор, пока он не станет правильным вопросом, это было бы лучше (и могло бы повысить ваши голоса). Попытка ответить на не вопрос просто побуждает людей не редактировать и не улучшать его. (Не отклоняя ваш ответ, но и не повышая его.) Тот факт, что запрашивающий может следить за вычислениями в отладчике, предполагает , что пользователь на самом деле может выполнять какие-то вычисления на основе конкретных выходных данных, чего, похоже, нет. Ожидание кода и информации означает, что вам нужно что-то уточнить при ответе. 🙂

2. Спасибо за ваши ответы. Я попытаюсь опубликовать несколько примеров кода

3. @Ken: Я с тобой не согласен. Да, больше информации и, что еще лучше, исходный код работали бы лучше, но он сказал, что пытался центрировать тексты, нарисованные с помощью textout. Так что я не угадывал. Если бы вы внимательно прочитали запрос, вы бы увидели, что он содержит гораздо больше информации, на которую вы, очевидно, обратили внимание в первую очередь.

4. Нет проблем. Пытаюсь помочь и вам, и оригинальному постеру, но, видимо, вы обиделись. Приношу свои извинения. (Но вы УГАДЫВАЛИ (кричали свое, не мое), потому что OP никогда не говорил, что выполнялись вычисления или какие данные / алгоритм использовались; Динеш просто сказал, что все работает на одной поверхности, а не на другой при использовании TextOut . «Когда я езжу на велосипеде, иногда он быстро останавливается, а в других случаях это занимает некоторое время». С какой скоростью двигался байк? Когда она быстро останавливается, это потому, что вы сильнее нажали на тормоз или потому, что врезались в дерево? Детали имеют значение. Впрочем, неплохое предположение.

5. @Ken: точка зрения принята. Также приношу свои извинения за то, что немного погорячился, спасибо за то, что отреагировал в такой дружелюбной манере. И теперь по теме: если он вызывает textout, он сам использует canvas, в textout есть только x, y и нет rect, поэтому, если ему нужно центрировать текст, ему нужно вычислить правильные координаты на основе размеров. Таким образом, у нас есть вызов textout, у нас есть вычисления, которые он выполняет сам, и то, что является пресловутым деревом тормозов, является предположением; ошибся ли расчет, был ли расчет основан на неправильных размерах, отличаются ли координаты и т.д., И т.д. Это предположение все верно.