Author Topic: Comments Flattener  (Read 8403 times)

0 Members and 1 Guest are viewing this topic.

nightslayer23

  • Newbie
  • *
  • Posts: 98
Comments Flattener
« on: September 13, 2019, 09:18:40 AM »
Could you translate a custom script for flattening all annotations, highlights and comments?

We've found these often drop off at the print level.

We have a current java script that does it perfect, but you have to do it file - by - file.

Be great if there was a way to do this as a batch.

the program that the script belongs in is: https://www.uvsar.com/projects/acrobat/flattener/

RTT

  • Administrator
  • *****
  • Posts: 918
Re: Comments Flattener
« Reply #1 on: September 14, 2019, 01:06:44 AM »
No internal code to do this, but here is a script to automate Acrobat Professional to do it.
Code: [Select]
var objShell = new ActiveXObject("shell.application");
var objFolder;
objFolder = objShell.BrowseForFolder(0, "Select the destination folder", 0x10, 0x11);

if (objFolder != null) {
    var DestFolder = objFolder.self.path;
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var app = pdfe.CreateObject("AcroExch.App");
    var baseDoc = pdfe.CreateObject("AcroExch.PDDoc");
    var ProgressBar = pdfe.ProgressBar;
    ProgressBar.max = pdfe.SelectedFiles.Count;

    for (var i = 0; i < pdfe.SelectedFiles.Count; i++) {
        try {
            FullPathFilename = pdfe.SelectedFiles(i).Filename;
            var Filename = FullPathFilename.substr(FullPathFilename.lastIndexOf('\\') + 1);
            var DestFullPathFilename = fso.BuildPath(DestFolder, Filename);

            if (FullPathFilename == DestFullPathFilename) {
                DestFullPathFilename = FullPathFilename.substr(0, FullPathFilename.lastIndexOf('.') - 1) + '_flattened.pdf';
            }

            pdfe.echo('Flattening: ' + FullPathFilename);
            ProgressBar.position = i + 1;

            baseDoc.Open(FullPathFilename);

            try {
                var JSObject = baseDoc.getJSObject();
                JSObject.addScript("flatten", "function flatten(){this.flattenPages();}flatten();");
                JSObject.removeScript("flatten");
                baseDoc.Save(1, DestFullPathFilename);
                pdfe.echo(" [OK]", 0, 1);
            } catch (err) {
                pdfe.echo(err, 0xFF0000);
                pdfe.echo("");
            }
            baseDoc.close();
        } catch (err) {
            pdfe.echo(err, 0xFF0000);
            pdfe.echo("");
        }
    }
    app.Exit();
    pdfe.echo('\nDone');
}

nightslayer23

  • Newbie
  • *
  • Posts: 98
Re: Comments Flattener
« Reply #2 on: September 16, 2019, 12:06:11 AM »
so this script is to be installed into acrobat correct?

this isn't a script we could add to the PDF Shell Tools context menu?


never-mind! I see it works from the context menu! fantastic..

what do I need to take out of this script so it is a save over original file ? I'd like to add the script to a super script that I have that checks size & orientation but flattens comments at the same time (which I've already put together). same with a version that checks size, orientation & coverage, would need it to flatten prior to checking for coverage.

RTT

  • Administrator
  • *****
  • Posts: 918
Re: Comments Flattener
« Reply #3 on: September 16, 2019, 12:17:15 AM »
so this script is to be installed into acrobat correct?
No. This is a PDF-ShellTools script, to run from the PDF-ShellTools scripts interface, so could be added to the PDF-ShellTools context menu. It just needs Acrobat Professional to be installed, as it uses it to do the work.

nightslayer23

  • Newbie
  • *
  • Posts: 98
Re: Comments Flattener
« Reply #4 on: September 16, 2019, 12:35:05 AM »
yes I worked out how to use it just after I posted.

please see my last post for other enquiry

RTT

  • Administrator
  • *****
  • Posts: 918
Re: Comments Flattener
« Reply #5 on: September 17, 2019, 01:06:22 AM »
what do I need to take out of this script so it is a save over original file ?
This should do it.
Code: [Select]
var app = pdfe.CreateObject("AcroExch.App");
var baseDoc = pdfe.CreateObject("AcroExch.PDDoc");

var ProgressBar = pdfe.ProgressBar;
ProgressBar.max = pdfe.SelectedFiles.Count;

for (var i = 0; i < pdfe.SelectedFiles.Count; i++) {
    try {
        ProgressBar.position = i + 1;
        var FileObj = pdfe.SelectedFiles(i);
        var FullPathFilename = FileObj.Filename;
        FileObj.Close();

        pdfe.echo('Flattening: ' + FullPathFilename);

        baseDoc.Open(FullPathFilename);

        try {
            var JSObject = baseDoc.getJSObject();
            JSObject.addScript("flatten", "function flatten(){this.flattenPages();}flatten();");
            JSObject.removeScript("flatten");
            baseDoc.Save(1, FullPathFilename);
            pdfe.echo(" [OK]", 0, 1);
        } catch (err) {
            pdfe.echo(err, 0xFF0000);
            pdfe.echo("");
        }
        baseDoc.Close();
    } catch (err) {
        pdfe.echo(err, 0xFF0000);
        pdfe.echo("");
    }
}
app.Exit();
pdfe.echo('\nDone');

nightslayer23

  • Newbie
  • *
  • Posts: 98
Re: Comments Flattener
« Reply #6 on: September 19, 2019, 12:52:24 AM »
excellent! thankyou

mike211175

  • Newbie
  • *
  • Posts: 1
Re: Comments Flattener
« Reply #7 on: January 06, 2020, 04:52:57 AM »
RTT,

I was hoping to ask you a question about the flattening script, and about how it runs into a security warning even though that security warning is not displayed in the metadata exporter.

I installed the flattening script provided on the above forum page into the shell tools manager and it show up under the "My scripts" tab and I was able to run it. Generally it worked. But it failed to flatten a pdf that was made by converting a clean page from Word to pdf and then digitally signing with Adobe - see attached the one page pdf document with the signature, and an image file of the error message when the flattening script was run.

I note that when running the totally separate script in your software for "Export metadata to MS Excel or OpenOffice Calc" the pdf with that signature is NOT indicated to have any enhanced security. i.e. the security is noted as "0" i.e. none.

I often want to run processes on pdf libraries and documents in that library that have electronic signatures may interfere with the process e.g. if I want to batch Bates stamp documents then the documents with electronic signatures may fail. So I need to pre-process the ones with signatures, and so have to identify them first.

One approach is to screen the library for docs with signatures, and I was to hoping to use your metadata export tool for that, but as noted it does not detect documents with signatures i.e. security settings are shown as "0" i.e. none. So then I thought to just flatten all of them before running the other processes, but as noted that failed too because I got the security warning error message.

Do you have a tool that will detect all pdfs (in a large library) that have electronic signatures? Can the metadata export tool be tweaked to do that? Alternatively, is there a way to flatten all docs in the library, including those with electronic signatures?

Thanks in advance for any input.

Your software looks good and if it is able to achieve the above I will certainly buy it!

Regards
Michael

RTT

  • Administrator
  • *****
  • Posts: 918
Re: Comments Flattener
« Reply #8 on: January 06, 2020, 03:48:15 PM »
I installed the flattening script provided on the above forum page into the shell tools manager and it show up under the "My scripts" tab and I was able to run it. Generally it worked. But it failed to flatten a pdf that was made by converting a clean page from Word to pdf and then digitally signing with Adobe - see attached the one page pdf document with the signature, and an image file of the error message when the flattening script was run.
The script automates Acrobat to do the flattening and Acrobat disables flattening of documents with digital signatures.

Quote
I note that when running the totally separate script in your software for "Export metadata to MS Excel or OpenOffice Calc" the pdf with that signature is NOT indicated to have any enhanced security. i.e. the security is noted as "0" i.e. none.
That security property is about the PDF password security functionality.

Quote
Do you have a tool that will detect all pdfs (in a large library) that have electronic signatures? Can the metadata export tool be tweaked to do that? Alternatively, is there a way to flatten all docs in the library, including those with electronic signatures?

Here is a script (also attached so you can easily import it with the PDF-ShellTools Manager), that you can use to get the list of digitally signed PDFs. Let me know if you need any modification to better fit your workflow.
Code: [Select]
var app = pdfe.CreateObject("AcroExch.App");
var baseDoc = pdfe.CreateObject("AcroExch.PDDoc");
var ProgressBar = pdfe.ProgressBar;
ProgressBar.max = pdfe.SelectedFiles.Count;
pdfe.echo('Digitally signed files:');
pdfe.echo(' ');
var count = 0;
for (var i = 0; i < pdfe.SelectedFiles.Count; i++) {
    try {
        var FullPathFilename = pdfe.SelectedFiles(i).Filename;
        pdfe.echo('Checking signatures: ' + FullPathFilename, 0, 2);
        ProgressBar.position = i + 1;

        baseDoc.Open(FullPathFilename);

        try {
            var JSObject = baseDoc.getJSObject();
            if (JSObject) {
                for (var fn = 0; fn < JSObject.numFields; fn++) {
                    var fname = JSObject.getNthFieldName(fn);
                    var field = JSObject.getField(fname);
                    if (field.type == "signature" && field.signatureValidate() > 1) {
                        pdfe.echo(FullPathFilename, 0, 2);
                        pdfe.echo(' ');
                        count++;
                        break;
                    }
                }
            }
        } catch (err) {
            pdfe.echo(FullPathFilename + ': ' + err, 0xFF0000, 2);
            pdfe.echo(' ');
        }
        baseDoc.Close();
    } catch (err) {
        pdfe.echo(err, 0xFF0000);
        pdfe.echo(' ');
    }
}
app.Exit();
if (count == 0) pdfe.echo('None found', 0, 2)
else pdfe.echo('Done', 0, 2);

nightslayer23

  • Newbie
  • *
  • Posts: 98
Re: Comments Flattener
« Reply #9 on: December 22, 2021, 12:12:06 AM »
Hi again!

is this also possible for tapping into Acrobat's preflight options?

Preflight > "Discard hidden layer content and flatten visible layers"


RTT

  • Administrator
  • *****
  • Posts: 918
Re: Comments Flattener
« Reply #10 on: December 27, 2021, 06:31:23 PM »
is this also possible for tapping into Acrobat's preflight options?
Preflight > "Discard hidden layer content and flatten visible layers"
Sure, but you will need to create a custom preflight profile to include that fixup. It seems only profiles can be executed from Acrobat javascript.
Create a new preflight profile, give it that "Discard hidden layer content and flatten visible layers" name (so the next script can find it) and add that fixup to it.
You can use the next PDF-ShellTools script to run it.
Code: [Select]
var oPreflight;
var app = pdfe.CreateObject("AcroExch.App");
var baseDoc = pdfe.CreateObject("AcroExch.PDDoc");
if (baseDoc.create()) {
    var JSObject = baseDoc.getJSObject();
    if (JSObject) {
        JSObject.addScript("getPreflightObj", "function getPreflightObj(){return Preflight}");
        oPreflight = JSObject.getPreflightObj();
        JSObject.removeScript('getPreflightObj');
        if (oPreflight != undefined) {
            pdfe.echo('Loading preflight profile');
            oProfile = oPreflight.getProfileByName('Discard hidden layer content and flatten visible layers');
            if (oProfile) {
                pdfe.echo(" [OK]", 0, 1);
            } else {
                pdfe.echo(" [not found]", 0xFF0000, 1);
            }
        }
    }
    baseDoc.Close();
}
if (oProfile) {
    var ProgressBar = pdfe.ProgressBar;
    ProgressBar.max = pdfe.SelectedFiles.Count;
    for (var i = 0; i < pdfe.SelectedFiles.Count; i++) {
        try {
            ProgressBar.position = i + 1;
            var FileObj = pdfe.SelectedFiles(i);
            var FullPathFilename = FileObj.Filename;
            FileObj.Close();
            pdfe.echo('Processing: ' + FullPathFilename);
            baseDoc.Open(FullPathFilename);
            try {
                var JSObject = baseDoc.getJSObject();
                if (JSObject) {
                    var PreflightResult = JSObject.preflight(oProfile);
                    if (PreflightResult.numFixed > 0) {
                        baseDoc.Save(1, FullPathFilename);
                        pdfe.echo(" [OK]", 0, 1);
                    } else {
                        pdfe.echo(" [fixup(s) not applied]", 0, 1);
                    }
                }
            } catch (err) {
                pdfe.echo(FullPathFilename + ': ' + err, 0xFF0000, 2);
                pdfe.echo(' ');
            }
            baseDoc.Close();
        } catch (err) {
            pdfe.echo(err, 0xFF0000);
            pdfe.echo(' ');
        }
    }
}
app.Exit();
pdfe.echo('Done');