0

I've had this problem for a while, now. Close to the end of my "Proofing" script, the currently opened document in InDesign is to be exported to two different .pdf files. The first is password-protected while the second is not. I don't seem to have any problems with the latter, but the former often becomes corrupted somehow and cannot be opened by any PDF reader, including Acrobat itself. Here's the code block that does the exporting (it is not runnable by itself, btw):

/********** BEGIN PDF EXPORTING **********/

// First, let's create and set PDF export preferences.
// This begins with creating a temporary preset if it doesn't already exist.
// This preset will be used for both the Proof page and the Cover sheet.
var tempPreset = app.pdfExportPresets.item("tempPreset");
try
{
    tempPreset.name;
}
catch (eNoSuchPreset)
{
    tempPreset = app.pdfExportPresets.add({name:"tempPreset"});
}
with (tempPreset)
{
    acrobatCompatibility = AcrobatCompatibility.ACROBAT_5;
    bleedMarks = false;
    colorBars = false;
    colorBitmapCompression = BitmapCompression.AUTO_COMPRESSION;
    colorBitmapQuality = CompressionQuality.MAXIMUM;
    colorBitmapSampling = Sampling.BICUBIC_DOWNSAMPLE;
    colorBitmapSamplingDPI = 300;
    compressTextAndLineArt = true;
    cropImagesToFrames = true;
    cropMarks = false;
    exportGuidesAndGrids = false;
    exportNonprintingObjects = false;
    exportReaderSpreads = false;
    exportWhichLayers = ExportLayerOptions.EXPORT_VISIBLE_PRINTABLE_LAYERS;
    generateThumbnails = false;
    grayscaleBitmapCompression = BitmapCompression.AUTO_COMPRESSION;
    grayscaleBitmapQuality = CompressionQuality.MAXIMUM;
    grayscaleBitmapSampling = Sampling.BICUBIC_DOWNSAMPLE;
    grayscaleBitmapSamplingDPI = 300;
    includeBookmarks = false;
    includeHyperlinks = false;
    includeSlugArea = false;
    includeStructure = true;
    monochromeBitmapCompression = MonoBitmapCompression.CCIT4;
    monochromeBitmapSampling = Sampling.BICUBIC_DOWNSAMPLE;
    monochromeBitmapSamplingDPI = 1200;
    omitBitmaps = false;
    omitEPS = false;
    omitPDF = false;
    optimizePDF = true;
    pageInformationMarks = false;
    pageMarksOffset = 0.0833;
    pdfMarkType = MarkTypes.DEFAULT_VALUE;
    printerMarkWeight = PDFMarkWeight.P25PT;
    registrationMarks = false;
    standardsCompliance = PDFXStandards.NONE;
    subsetFontsBelow = 100;
    thresholdToCompressColor = 450;
    thresholdToCompressGray = 450;
    thresholdToCompressMonochrome = 1800;
    useDocumentBleedWithPDF = false;
}
currentProcess.text = "PDF export preferences"; progressWin.show();
progressIndividual.value++; if (aProducts.length > 1) {progressOverall.value++;}

// Now let's actually set the export preferences.  These are for the proof page.
with (app.pdfExportPreferences)
{
    pageRange = proofRange;
    useSecurity = true;
    disallowChanging = true;
    disallowCopying = false;
    disallowDocumentAssembly = true;
    disallowExtractionForAccessibility = false;
    disallowFormFillIn = true;
    disallowHiResPrinting = true;
    disallowNotes = true;
    disallowPlaintextMetadata = true;
    disallowPrinting = false;
    changeSecurityPassword = "sky";
    if (multiColor)
    {
        pageRange = colorTable.toString();
    }
    if (currentProduct.pLabel != "")
    {
        pageRange += "," + labelPage.name;
    }
}
currentProcess.text = "Exporting PDF proof page"; progressWin.show();
progressIndividual.value++; if (aProducts.length > 1) {progressOverall.value++;}

// Before exporting the Proof page(s), hide the color bar on multicolor products.
if (multiColor) {document.layers.item("COLOR BAR").visible = false;}

// Then we save the proof page.
document.exportFile(ExportFormat.PDF_TYPE, File(jobFolder.toString() + "/" + saveName + ".pdf"), false, tempPreset);

When that produced corrupted PDFs once in a while, I thought that perhaps it was our less-than-ideal network structure causing the problem, so I instead tried exporting the PDF file to the local hard drive rather than directly to the network, then having the file be moved to the network afterward. So, the last line in the above code block was replaced with:

// First, to the local HDD.
document.exportFile(ExportFormat.PDF_TYPE, File("~/Documents/" + saveName + ".pdf"), false, tempPreset);
$.sleep(1000);
File("~/Documents/" + saveName + ".pdf").copy(File(jobFolder.toString() + "/" + saveName + ".pdf"));
$.sleep(1000);
File("~/Documents/" + saveName + ".pdf").remove();

I even added in those 1-second delays, just in case. Sadly, this hasn't helped. I am still getting a corrupted PDF every now and then. If there is any pattern to the corrupted files, I haven't been able to discern it. Does anyone have any thoughts?

Sturm
  • 689
  • 2
  • 23
  • 52
  • my thought is: what does the corruption look like? Is there still data in the file (not zero K)? If there is data, if you change the file extension to ".txt" and open in TextWrangler, what does it look like? – CRGreen Dec 20 '13 at 08:31
  • Sorry, I never really tried your suggestion about seeing what the corruption looks like. Instead, I created a workaround that I'll post in a moment. – Sturm Mar 31 '14 at 17:00

1 Answers1

0

It finally hit me that, if the corrupted files are not able to be opened in Acrobat, then why not just test for that after the file is created? So I created a loop that exports the PDF file and tries to open it in Acrobat. If it opens fine, then it prints and closes the file, returning a "true" message. If it is unable to do so, then it returns a "false" message to the script. Then the loop repeats so long as that message is "false". While not a great fix for the underlying cause (whatever it may be), it at least is a workaround that will do just fine for our needs. The trick is that, because we work with Macs, we have to route the message through an AppleScript instead of using BridgeTalk to communicate directly with Acrobat.

Here's the code snippet from the main InDesign script which goes through the PDF-checking loop:

// Then we save the proof page.
// The loop is to make sure that the file was saved properly.
var validFile = false; // Flag that states whether or not the file is corrupted after saving.
var rString; // String returned from Acrobat that should be either "true" or "false".
var testAndPrintFile = File("~/Documents/testAndPrint.applescript"); // The applescript file that calls Acrobat and runs a folder-level script.
var pdfFile; // A String of the filename & path that will be passed to through the applescript file to Acrobat.
var pdfArray = new Array(4); // An array to send to Acrobat.  [0] is the PDF filename as a String,
                             // [1] is duplex if true, [2] is the printer name, and [3] is to enable printing.
if (multiTwoSided || twoPages) pdfArray[1] = "true";
    else pdfArray[1] = "false";
pdfArray[2] = localPrinter;
pdfArray[3] = "true";
while (!validFile)
{
    $.writeln("If this message is seen more than once, then the Proof PDF was corrupted.");
    try
    {
        document.exportFile(ExportFormat.PDF_TYPE, File(jobFolder.toString() + "/" + saveName + ".pdf"), false, tempPreset);
    }
    catch (e)
    {
        alert("Could not save the Proof PDF.  Please close any open copies of the Proof PDF, then save and print it manually.");
    }
    pdfFile = jobFolder.toString() + "/" + saveName + ".pdf";
    pdfArray[0] = pdfFile;
    $.writeln("pdfArray contains: " + pdfArray);
    try
    {
        rString = app.doScript(testAndPrintFile, ScriptLanguage.APPLESCRIPT_LANGUAGE, pdfArray);
        validFile = rString == "true";
        // validFile = true;
        $.writeln("validFile is " + validFile);
        if (!validFile)
        {
            alert("It seems that the file " + unescape(pdfArray[0]) + " is corrupted.  Will try to export it again.");
        }
    }
    catch (e)
    {
        $.writeln("ERROR at line number " + e.line);
        $.writeln(e.description);
        throw new Error("ERROR at line number " + e.line + "\n" + e.description);
    }
}

The testAndPrint.applescript file that this loop calls:

set pdfFile to item 1 of arguments
set duplexed to item 2 of arguments
set printerName to item 3 of arguments
set printEnabled to item 4 of arguments
tell application "Adobe Acrobat Pro"
    set result to do script ("testAndPrint(\"" & pdfFile & "\", \"" & duplexed & "\", \"" & printerName & "\", \"" & printEnabled & "\");")
end tell
return result

And, finally, the folder-level Javascript file that is loaded into memory when Acrobat starts, ready to have its function called by the above Applescript file:

var testAndPrint = app.trustedFunction(function (fName, duplexed, sPrinterName, bEnablePrinting)
{
    var success = true;
    app.beginPriv();
    console.println("fName is " + unescape(fName));
    console.println("sPrinterName is " + sPrinterName);
    try
    {
        var printDoc = app.openDoc(unescape(fName));
        var pp = printDoc.getPrintParams();
        if (duplexed == "true") pp.DuplexType = pp.constants.duplexTypes.DuplexFlipLongEdge;
            else pp.DuplexType = pp.constants.duplexTypes.Simplex;
        pp.printerName = sPrinterName;
        pp.interactive = pp.constants.interactionLevel.silent;
        pp.pageHandling = pp.constants.handling.none;
        if (bEnablePrinting == "true") printDoc.print({bUI: false, bSilent: true, bShrinkToFit: false, printParams: pp});
        printDoc.closeDoc(true);
    }
    catch (e)
    {
        console.println("ERROR at line number " + e.lineNumber);
        console.println(e.message);
        success = false;
    }
    app.endPriv();
    console.println("success is " + success);
    return success;
});

I hope that, perhaps, this information might be useful to anyone else running into a similar problem. It's not pretty, of course, but it certainly gets the job done.

Sturm
  • 689
  • 2
  • 23
  • 52