Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to automatically print pdfs with detailed options?

Here's the scenario I am trying to solve. The company I work at has to print multiple pdfs everyday for students. The last page of each pdf must be printed in blue paper. Our current process is to manually print the pdfs and send all pages except the last to one printer that has white paper stocked and then send the last page to another printer which has blue paper in its tray. This is time-consuming and tedious. I have created a PowerShell script that will takes all pdfs in a given folder and first splits the pdfs into two parts, the first being all pages but the last and the second being the last page. Then the script sends each pdf to the appropriate printer.

However these PDFs are secured, so the script doesn't work. Typically they are automatically decrypted after a few seconds after opening Adobe Reader, but since the script prints them right away there is not time for decoding.

I am wondering:

  1. Is there a way to resolve the encryption issue in Powershell and
  2. Furthermore, be able to select a tray when automatically printing to correctly print the colored pages using only one printer. (This would be ideal as the pages will remain in order. Currently, we don't have a printer with two trays, but as the company expands we most certainly will.)

From what I know, I believe #2 would require C# so I am willing to scrap my Powershell script if it means being able to automatically select the paper tray.

Here's my current script (it is not pretty, sorry)

# Set Up Folders
$input = "C:\batchPrintPKs\unsplit_pdfs"
$output_f = "C:\batchPrintPKs\split_pdfs_f"
$output_l = "C:\batchPrintPKs\split_pdfs_l"

# Load Adobe and PDFtk (Used to split PDFs)
$adobe= 'C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe'
$pdftk = "C:\Program Files (x86)\PDFtk Server\bin\pdftk.exe"

# Printer Names
$printername_brother='Brother DCP-L2540DW series Printer'
$printername_epson='Epson854235 (ET-4550 Series)'


# Create List of Paths to Pdfs to Work With
$files1 = Get-ChildItem “c:\batchPrintPKs\unsplit_pdfs\*.pdf”

# For All PDFs in unsplit_pdfs
foreach ($file1 in $files1){

    # Calculating Indexing
    $Match = 'NumberOfPages: (\d+)'
    $NumberOfPages = [regex]::match((& $pdftk $file1 dump_data),$Match).Groups[1].Value
    $SecondToLastPage = $NumberOfPages - 1 

    # Making PDF of pages 1 - Second to Last
    Get-Childitem -path $input -filter *.pdf -recurse | foreach {            
        & $pdftk $_.Fullname cat 1-$SecondToLastPage output $output_f\"f_"$_
        }

    # Making PDF of last page
    Get-Childitem -path $input -filter *.pdf -recurse | foreach {            
        & $pdftk $_.Fullname cat $NumberOfPages output $output_l\"l_"$_
        }

    # Removing File
    Remove-Item $file1
}
sleep(5)

# Brother
    # Create List of Paths to Pdfs to Work With
    $files2 = Get-ChildItem “c:\batchPrintPKs\split_pdfs_f\*.pdf”
    

    # Print Each File to the Epson
    foreach ($file2 in $files2){
        $arglist1='/t "{0}" "{1}"' -f $file2, $printername_Brother
        Start-Process $adobe $arglist1

        sleep(2)
        # Removing File
        Remove-Item $file2
    }

# Epson
    # Create List of Paths to Pdfs to Work With
    $files3 = Get-ChildItem “c:\batchPrintPKs\split_pdfs_l\*.pdf”
    
    # Print Each File to the Epson
    foreach ($file3 in $files3){
        $arglist2='/t "{0}" "{1}"' -f $file3, $printername_Epson
        Start-Process $adobe $arglist2

        sleep(2)
        # Removing File
        Remove-Item $file3
    }
like image 217
Kurt Hoelsema Avatar asked Jan 17 '18 15:01

Kurt Hoelsema


1 Answers

You could easily make this with Adobe API via COM object.

Here is an exampe of printing pages range:

# path to PDF file
$PDF = 'C:\Users\Kiril\Downloads\file.pdf'
# declare a COM object for the Acrobat application
$App = New-Object -ComObject AcroExch.App
# declare a COM object for PDDoc
$PDDoc = New-Object -ComObject AcroExch.PDDoc
# open a PDF
$PDDoc.Open($PDF)
# get the number of pages in the pdf document
$NumPages = $PDDoc.GetNumPages()
# this hides the acrobat instance if it's visible
$App.Hide()
# this displays the document in the acrobat instance and creates an AVDoc COM object
$AVDoc = $PDDoc.OpenAVDoc("")
# printing particular pages range
$AVDoc.PrintPages(0, 1, $NumPages - 1, 0, 0)

The method PrintPages of $AVDoc object is well described on reference document.

Please see Acrobat® and PDF Library API Reference

like image 69
Kirill Pashkov Avatar answered Oct 22 '22 14:10

Kirill Pashkov