Экспорт в PDF классом PDFReportGenerator через PDF принтер
Добавлено: 31 Август 2019, 19:35
Выложил на ftp в каталог "_Templates". Файл - PDFGenerator.zip. Назовём версией 1.0b3.
Краткое описание.
1. Проблема. Стандартный класс SV PDFReportGenerator не работает с кириллицей (определённо и с другими национальными символами). Костыль в виде опции "Use Scan Copy" работает неудовлетворительно, программа гарантированно падает на многостраничных документах. Да и созданный с этой опцией документ имеет непозволительно большой объём (используется перобразование wmf->png, и уже картинка png экспортируется в pdf файл).
2. Предлагаемое решение. Предлагается допилить стандартный класс PDFReportGenerator. При наличии в системе установленного PDF принтера отправлять созданный отчет на него, а распарсивание wmf страниц классом PDFReportGenerator не использовать. Благодарю Игоря Столярова за правильный пинок в правильном направлении.
3. Как работает решение. После выбора пользователем в окне предварительного просмотра пункта меню "Сохранить как..->PDF" и выбора им файла (аналогично при "фоновом экспорте") сначала проверяем в реестре наличие установленного принтера "Microsoft Print to PDF". Если его нет, то проверяем наличие какого-либо другого принтера PDF (проверяем наличие в названии подстроки "PDF"). Если не найден ни один принтер, то используем стандартное распарсивание wmf страниц классом PDFReportGenerator. В случае наличия установленного принтера PDF создаём пустой отчёт, создаём для него очередь wmf-файлов, копируем в эту очередь данные из очереди оригинального отчёта и посылаем этот отчёт на PDF принтер. Далее проверяем созданный файл на наличие в заголовке метки о том, что это PostScript файл (оказалось, что это типичный случай при работе с PDF принтерами). Если полученный файл PostScript, то конвертируем его конвертером GhostScript в PDF.
4. Технические детали. Основное изменение находится в файле "\libsrc\abprpdf.clw" в методе PDFReportGenerator.IReportGenerator.AskProperties. Т.к. пришлось изменить входные параметры метода, то нужно сделать изменения в файле ABRPTGEN.INT в интерфейсе IOutputGeneratorTarget и в файлах abprtext.clw (abprxml.clw, abprhtml.clw, abprpng.clw) в методах (XXX)ReportGenerator.IReportGenerator.AskProperties. Также необходимо провести изменения в файле abreport.clw в методах PrintPreviewClass.ParseImages и ReportManager.PrintReport. Файлы конвертера GhostScript (лежат в каталоге "\bin") необходимо положить в рабочий каталог вашей программы. Мои правки помечены "*** KreatoR ***".
5. Бонусы. Можете посмотреть и использовать изменённый класс превьювера (изменения касаются в основном внешнего вида, но добавлено, например, поле "Страниц для печати" на основное окно превьювера). Также можете использовать изменённый ProcessClass c внедрённым классом TaskbarList (особые благодарности за этот класс уважаемому Деде Пахому).
Если кто будет пробовать, не забывайте сделать копии каталогов "\libsrc" и "\templates" на всякий случай. Проблемы, пожелания готов выслушать. Отлажено на C11 (думаю, С10 и т.д. без проблем, С6.3 и ниже не смотрел). Проверена работоспособность на Win7 и Win10 с принтерами "Microsoft Print to PDF", "Adobe PDF", "Bullzip PDF". Если в системе гарантированно присутствует "Microsoft Print to PDF", то конвертер GhostScript не нужен. Принтер "doPDF" не подходит совсем, он не поддерживает печать в файл.
Краткое описание.
1. Проблема. Стандартный класс SV PDFReportGenerator не работает с кириллицей (определённо и с другими национальными символами). Костыль в виде опции "Use Scan Copy" работает неудовлетворительно, программа гарантированно падает на многостраничных документах. Да и созданный с этой опцией документ имеет непозволительно большой объём (используется перобразование wmf->png, и уже картинка png экспортируется в pdf файл).
2. Предлагаемое решение. Предлагается допилить стандартный класс PDFReportGenerator. При наличии в системе установленного PDF принтера отправлять созданный отчет на него, а распарсивание wmf страниц классом PDFReportGenerator не использовать. Благодарю Игоря Столярова за правильный пинок в правильном направлении.
3. Как работает решение. После выбора пользователем в окне предварительного просмотра пункта меню "Сохранить как..->PDF" и выбора им файла (аналогично при "фоновом экспорте") сначала проверяем в реестре наличие установленного принтера "Microsoft Print to PDF". Если его нет, то проверяем наличие какого-либо другого принтера PDF (проверяем наличие в названии подстроки "PDF"). Если не найден ни один принтер, то используем стандартное распарсивание wmf страниц классом PDFReportGenerator. В случае наличия установленного принтера PDF создаём пустой отчёт, создаём для него очередь wmf-файлов, копируем в эту очередь данные из очереди оригинального отчёта и посылаем этот отчёт на PDF принтер. Далее проверяем созданный файл на наличие в заголовке метки о том, что это PostScript файл (оказалось, что это типичный случай при работе с PDF принтерами). Если полученный файл PostScript, то конвертируем его конвертером GhostScript в PDF.
4. Технические детали. Основное изменение находится в файле "\libsrc\abprpdf.clw" в методе PDFReportGenerator.IReportGenerator.AskProperties. Т.к. пришлось изменить входные параметры метода, то нужно сделать изменения в файле ABRPTGEN.INT в интерфейсе IOutputGeneratorTarget и в файлах abprtext.clw (abprxml.clw, abprhtml.clw, abprpng.clw) в методах (XXX)ReportGenerator.IReportGenerator.AskProperties. Также необходимо провести изменения в файле abreport.clw в методах PrintPreviewClass.ParseImages и ReportManager.PrintReport. Файлы конвертера GhostScript (лежат в каталоге "\bin") необходимо положить в рабочий каталог вашей программы. Мои правки помечены "*** KreatoR ***".
5. Бонусы. Можете посмотреть и использовать изменённый класс превьювера (изменения касаются в основном внешнего вида, но добавлено, например, поле "Страниц для печати" на основное окно превьювера). Также можете использовать изменённый ProcessClass c внедрённым классом TaskbarList (особые благодарности за этот класс уважаемому Деде Пахому).
Если кто будет пробовать, не забывайте сделать копии каталогов "\libsrc" и "\templates" на всякий случай. Проблемы, пожелания готов выслушать. Отлажено на C11 (думаю, С10 и т.д. без проблем, С6.3 и ниже не смотрел). Проверена работоспособность на Win7 и Win10 с принтерами "Microsoft Print to PDF", "Adobe PDF", "Bullzip PDF". Если в системе гарантированно присутствует "Microsoft Print to PDF", то конвертер GhostScript не нужен. Принтер "doPDF" не подходит совсем, он не поддерживает печать в файл.