use strict; use warnings; #---- Time Module use POSIX qw(strftime); use Time::Local; #---- File Modules use Cwd; use File::Basename; use File::Spec::Win32; #---- OLE Modules use Win32::OLE qw(in with); use Win32::OLE::Const 'Microsoft Word'; # fetch list of Word Constants (wdPrintAllDocument, ... use Win32::OLE::Variant; #----Interupt Handler $SIG{ 'INT' } = "_interruptHandler"; #---- Define Boolean Constant Values use constant TRUE => 1; use constant FALSE => 0; use constant CURRENTDIR => cwd(); # Current Directory #---- Define Pathes my $sOutputPath = "pdf"; # Output Path Option my $sDirname = "c:/temp/perl/office2pdf/samples"; # Directory with the files to convert #---- Various Variables my $word = undef; # Word instance my $excel = undef; # Excel instance my $sInFilename = ""; # Input Filename my $sOutFilename = ""; # Output Filename #---- Printer settings my $sPrinter = "3-Heights(TM) PDF Producer"; # Printer use to 'print to' #---- Time settings my $tStart = ""; # Time start my $tEnd = ""; # Time end my $tDiff = ""; # Time difference my $sFile2Convert = ""; # Filename of the file to convert my $iSheetCount = ""; # Sheet counter my $sSimpleFilenameTmp = ""; #============================ Main process begin ============================ #---------------------------------------------------------------------------- # Start Process #---------------------------------------------------------------------------- &_main(); exit; #---------------------------------------------------------------------------- # Main Process #---------------------------------------------------------------------------- sub _main(){ #---- Open directory with all Microsoft Office files to convert opendir(DIR, $sDirname) or die "can't opendir $sDirname: $!"; #---- Loop through every file while (defined($sInFilename = readdir(DIR))) { #---- Office conversion #---- Check if it is a DOC or an XLS file if( ($sInFilename =~ /.doc/) || ($sInFilename =~ /.xls/) ){ #---- Check & Set Parameters &_setFilename(); } if($sInFilename =~ /.doc/) { #---- Convert Word to PDF &_convertWord2PDF(); } elsif($sInFilename =~ /.xls/){ #---- Convert Excel to PDF &_convertExcel2PDF(); } } closedir(DIR); } #============================= Main process end ============================= #---------------------------------------------------------------------------- # Word to PDF #---------------------------------------------------------------------------- sub _convertWord2PDF(){ my $docTmp = undef; my $CurrentPrinterTmp = ""; #---- Check for Microsoft Word eval {$word = Win32::OLE->GetActiveObject('Word.Application') || Win32::OLE->new('Word.Application')}; if ($@){ &_printErrorMsg("E999: Word not installed, leaving...\n"); exit -999; } #---- Set Microsoft Word Warning level eval {Win32::OLE->Option(Warn => 3)}; if ($@){ &_printErrorMsg("E997: Error when setting Warning level, leaving...\n"); exit -997; } #---- Open file eval {$docTmp = $word->{'Documents'}->Open($sInFilename)}; if ($@){ &_printErrorMsg("E996: Not able to open " . $sInFilename . ", leaving...\n"); exit -996; } #---- Set needed Printer eval {$word->{'ActivePrinter'} = $sPrinter}; if ($@ || substr( $word->{'ActivePrinter'}, 0, length($sPrinter)) ne $sPrinter){ &_printErrorMsg("E995: Not able to set " . $sPrinter . " as printer, leaving...\n"); exit -995; } #---- Print file $docTmp->PrintOut({ PrintToFile => 1, OutputFileName => $sOutFilename, Background => 0, Append => 0, Range => wdPrintAllDocument, Item => wdPrintDocumentContent, Copies => 1, PageType => wdPrintAllPages, }); #--- Force close without saving eval {$docTmp = $word->{'Documents'}->Close({ SaveChanges => wdDoNotSaveChanges })}; if ($@){ &_printErrorMsg("E994: Not able to close " . $sInFilename . ", leaving...\n"); exit -994; } #---- Do not change the following 3 lines or delete them. #---- If the order is change or one of the statement is missing, only ONE DOC will be convert. #---- After that a error comes up. undef $docTmp; $word->Quit; undef $word; } #---------------------------------------------------------------------------- # Excel to PDF #---------------------------------------------------------------------------- sub _convertExcel2PDF(){ my $xlsTmp = undef; my $CurrentPrinterTmp = ""; #---- Check for Microsoft Excel and use the active Excel application or open new eval {$excel = Win32::OLE->GetActiveObject('Excel.Application') || Win32::OLE->new('Excel.Application', 'Quit')}; if ($@){ &_printErrorMsg("E999: Excel not installed, leaving...\n"); exit -999; } #---- Set Microsoft Excel Warning level eval {Win32::OLE->Option(Warn => 3)}; if ($@){ &_printErrorMsg("E997: Error when setting Warning level, leaving...\n"); exit -997; } #---- Open file eval {$xlsTmp = $excel->{'Workbooks'}->Open($sInFilename)}; if ($@){ &_printErrorMsg("E996: Not able to open " . $sInFilename . ", leaving...\n"); exit -996; } #---- Set needed Printer eval {$excel->{'ActivePrinter'} = $sPrinter}; if (substr( $excel->{'ActivePrinter'}, 0, length($sPrinter)) ne $sPrinter){ &_printErrorMsg("E995: Not able to set " . $sPrinter . " as printer, leaving...\n"); exit -995; } #---- Count the sheets within the Excel file $iSheetCount = $xlsTmp->Sheets->Count(); #---- Loop to print all sheets within the Excel file for(my $iSheetNo = 1; $iSheetNo <= $iSheetCount; $iSheetNo++) { #---- Set Output Filename $sOutFilename = $sOutputPath . "\\" . $sSimpleFilenameTmp . "(" . $xlsTmp->Worksheets($iSheetNo)->Name . ").pdf"; #---- Print file $xlsTmp->Worksheets($iSheetNo)->PrintOut({ PrintToFile => 1, PrToFileName => $sOutFilename, Copies => 1, }); } $xlsTmp->Close; #--- Force close without saving eval {$xlsTmp = $excel->{'Workbooks'}->Close()}; if ($@){ &_printErrorMsg("E994: Not able to close " . $@ . " " .$sInFilename . ", leaving...\n"); exit -994; } undef $xlsTmp; } #---------------------------------------------------------------------------- # Set Filenames #---------------------------------------------------------------------------- sub _setFilename(){ #---- Fetch Input Filename $sInFilename = $sDirname."/".$sInFilename; $sSimpleFilenameTmp = fileparse($sInFilename, qr{\..*}); #---- Set Output Path & Filename $sOutputPath = &_getWin32Path($sOutputPath, TRUE); # remove last Slash/Backslash ../ and so on from Path $sOutFilename = $sOutputPath . "\\" . $sSimpleFilenameTmp . ".pdf"; # Output Filename } #---------------------------------------------------------------------------- # Get Path without last Slash/Backslash #---------------------------------------------------------------------------- sub _getWin32Path(){ (my $sPathPar) = $_[0]; (my $bNOFilePar) = $_[1]; (my $sDriveTmp, my $sDirTmp, my $sFileTmp) = File::Spec::Win32->splitpath($sPathPar, $bNOFilePar); if ($sDriveTmp eq ""){ $sPathPar = CURRENTDIR . "\\" . $sPathPar; } return File::Spec::Win32->canonpath($sPathPar); } #---------------------------------------------------------------------------- # Perl Interrupt Handler #---------------------------------------------------------------------------- sub _interruptHandler() { $SIG{ 'INT' } = "IGNORE"; &_printErrorMsg("E001: Unknown Error, leaving...\n"); exit -1; } #---------------------------------------------------------------------------- # Protocol and Print Message #---------------------------------------------------------------------------- sub _printErrorMsg(){ (my $sMsgPar) = $_[0]; $sMsgPar = &_getFormattedMsg($sMsgPar); print $sMsgPar; return; } #---------------------------------------------------------------------------- # Return formatted Message (with timestamp) #---------------------------------------------------------------------------- sub _getFormattedMsg(){ (my $sMsgPar) = $_[0]; $sMsgPar = "[" . strftime("%Y.%m.%d_%H:%M:%S", localtime()) . "] " . $sMsgPar; return $sMsgPar; } __END__