Недавно понадобилось в один свой проект автоматической печати добавить возможность печати xls(x), doc(x) и pdf. Программа в фоне опрашивает указанные ссылки, и если что-то есть, делает скрины страниц и автоматически выводит на указанный принтер. Теперь люди хотят не только скрины.
Поэтому сделал утилитку для закачки и печати указанных форматов. Чтобы заново не вспоминать в следующий раз и не рыть исходники привожу тут листинги. Мало ли кому пригодится. Фишка только в том, что печать происходит на указанный принтер, а не на используемый по умолчанию.
Печать doc(x)
Конечно же используем MSWord в качестве сервера автоматизации.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
// печать doc(x) function PrintWord(const AFileName, APrinter: String): Boolean; var WordApp: OLEVariant; begin Result := FileExists(AFileName); if not Result then begin // возможно, лог Exit; end; WordApp := CreateOleObject('Word.Application'); try // запрет сообщений WordApp.DisplayAlerts:= false; // открыть документ WordApp.Documents.Open(AFileName); if not APrinter.IsEmpty then // указать используемый принтер WordApp.ActivePrinter := APrinter; // печать WordApp.ActiveDocument.PrintOut() finally if not VarIsEmpty(WordApp) then begin WordApp.Quit; WordApp := Unassigned; end; end; end; |
Указание принтера явно происходит в строке
1 |
WordApp.ActivePrinter := APrinter; |
Печать xls(x)
Для Excel указание принтера происходит хитрее. В коде нет ошибки, он компилится и прекрасно работает, хоть и подчеркнет, как ошибку. Попробуйте сами.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
// печать xls(x) function PrintExcel(const AFileName, APrinter: String): Boolean; var ExcelApp: OLEVariant; begin Result := FileExists(AFileName); if not Result then begin // возможно, лог Exit; end; ExcelApp := CreateOleObject('Excel.Application'); try // запрет сообщений ExcelApp.DisplayAlerts:= false; // открыть книгу ExcelApp.Workbooks.Open(AFileName); // задать ориентацию страниц ExcelApp.ActiveSheet.PageSetup.Orientation := xlLandscape; if APrinter.IsEmpty then // печать на текущий принтер ExcelApp.Worksheets.PrintOut() else begin // печать на указанный принтер ExcelApp.Worksheets.PrintOut(ActivePrinter:= APrinter); end; finally // освободить if not VarIsEmpty(ExcelApp) then begin ExcelApp.Quit; ExcelApp := Unassigned; end; end; end; |
Печать PDF
Если офис установлен повсеместно, то Adobe Reader далеко не всегда. Тяжел, неповоротлив, надоедлив. Поэтому для печати используем SumatraPDF. Утилиту надо скачать и положить рядом с проектом. Установки не требует.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
const // параметры командной строки // https://www.sumatrapdfreader.org/docs/Command-line-arguments SumatraPDF = 'SumatraPDF.exe'; // печать pdf function PrintPDF(const AFileName, APrinter: String): Boolean; var PrintCommand: String; begin Result := FileExists(AFileName); if not Result then begin // возможно, лог end; Result := FileExists(SumatraPDF); if not Result then begin // возможно, лог end; if APrinter.IsEmpty then PrintCommand := '-print-to-default' else PrintCommand := '-print-to "' + APrinter + '"'; PrintCommand := PrintCommand + ' "'+AFileName+'"'; Result := ShellExecute (0, 'open', PChar (SumatraPDF), PChar(PrintCommand), nil, SW_HIDE)>32; end; |
Возможно, потребуется более гибкая настройка вывода на принтер. Для этих целей используем параметры командной строки.
Использование
Предположим, что это не консольное приложение, т.к. окна пользователю показывать не хотим. Все происходит автоматически и в фоновом режиме. Но между тем, предполагается запуск из командной строки, где первым параметром указан файл, вторым — принтер.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
program off_print; {$APPTYPE GUI} uses Windows, Classes, SysUtils, ShellApi, StrUtils, ComObj, Variants, {$IF CompilerVersion >= 23} Vcl.Printers, {$ELSE} Printers, {$IFEND} Excel2000; //... // попытка найти принтер в списке function IndexOfStrings(AList: TStrings; const AValue: String): Integer; var i: Integer; s, v: String; begin v := ReplaceStr(AnsiLowerCase(AValue),' ',''); for i := 0 to AList.Count-1 do begin s := ReplaceStr(AnsiLowerCase(AList[i]),' ',''); if AnsiCompareStr(s,v) = 0 then begin Result := i; Exit; end; end; Result := -1; end; var PrinterIndex: Integer; PrinterName: String; FileName: String; FileExt: String; begin FileName := ParamStr(1); PrinterName := ParamStr(2); if FileName = '/plist' then begin MessageBox(0,PChar(Printer.Printers.Text),'Printers',MB_OK); Exit; end; FileExt := AnsiLowerCase(ExtractFileExt(FileName)); FileName := ExpandFileName(FileName); PrinterIndex := IndexOfStrings(Printer.Printers, PrinterName); if PrinterIndex < 0 then PrinterName := '' else PrinterName := Printer.Printers[PrinterIndex]; if pos ('.xls',FileExt) > 0 then PrintExcel(FileName, PrinterName) else if pos ('.doc',FileExt) > 0 then PrintWord(FileName, PrinterName) else if pos ('.pdf',FileExt) > 0 then PrintPDF(FileName, PrinterName) ; end. |
Друзья, спасибо за внимание!
Подписывайтесь на телегу.
Может быть знаете еще простые способы печати? Поделитесь в комментариях )