Extendscript批量保存PDF

时间:2014-04-08 16:07:37

标签: javascript directory adobe-illustrator extendscript

我需要一点帮助。我想要一个脚本,将所有子文件夹中的所有AI文件转换为PDF并将它们放在根目录下的单个文件夹中,我希望它跳过任何名为" Resources"的文件夹。我找到了一个主要完成我需要它的脚本的脚本,并且我已经进一步修改它以满足我们的确切需求。尽管如此,我仍然在努力解决它的两个问题。第33和80行现在是我的问题。

#target illustrator

main();

//
function main() {

          var topLevel = Folder.selectDialog( 'Select the top level folder to start converting AI files to PDFX files' );

          var proofFolder = new Folder( topLevel + '/Proofs2/');
                    proofFolder.create();


          if ( topLevel != null ) {

                    processDocs( recursiveFolders( topLevel, /\.ai$/i ), getPDFOptions() );

          };

};

//
function processDocs( aiFiles, opts ) {

          var i, baseName, doc, saveFile;

          for ( i = 0; i < aiFiles.length; i++ ) {

                    doc = app.open( aiFiles[i] );

                    baseName = decodeURI( doc.name.match( /(.*)\.[^\.]+$/ )[1] );

//这是第33行// saveFile = File(proofFolder.path + baseName +&#39; .pdf&#39;);

                    doc.saveAs( saveFile, opts );

                    doc.close( SaveOptions.DONOTSAVECHANGES );

          };

};

//
function getPDFOptions() {

    var pdfSaveOpts = new PDFSaveOptions();

    pdfSaveOpts.acrobatLayers = true;
    pdfSaveOpts.colorBars = false;
    pdfSaveOpts.colorCompression = CompressionQuality.AUTOMATICJPEGHIGH;
    pdfSaveOpts.compressArt = true;
    pdfSaveOpts.embedICCProfile = true;
    pdfSaveOpts.enablePlainText = true;
    pdfSaveOpts.generateThumbnails = true;
    pdfSaveOpts.optimization = true;
    pdfSaveOpts.pageInformation = true;
    pdfSaveOpts.preserveEditability = true;
    pdfSaveOpts.pDFXStandard = PDFXStandard.PDFX1A2001;
    pdfSaveOpts.viewAfterSaving = false;


    return pdfSaveOpts;

};

//
function recursiveFolders( fold, exp ) {

          var fileList = Array(); // Our matching files…

          getFiles( fold, exp, fileList );

          return fileList;

};

//
function getFiles( fold, exp, array ) {

//这是第80行// if(Folder.name!== / \ Resources $ /){

          var i, temp;

          temp = Folder( fold ).getFiles(); // All files and folders…

          for ( i = 0; i < temp.length; i++ ) {

                    if ( temp[i] instanceof File && RegExp( exp ).test( temp[i].fsName ) ){

                              array.push( temp[i] );

                    };


                    if ( temp[i] instanceof Folder ) {

                              getFiles( temp[i].fsName, exp, array );

                    };

          };

          return array;

        };

};

1 个答案:

答案 0 :(得分:1)

第33行:

Javascript中的变量是它们定义的函数的本地变量。也就是说,如果你尝试

a();

function a()
{
    var a1 = 1;
    b();
}

function b()
{
    alert ("var a1 = "+a1);
}

您会在功能a1中找到b 未定义。两个常见的解决方案(可能还有更多)是将变量放在函数定义中:

b(a1);
..
function b (myVarArg)
{
    alert ("var a1 = "+myVarArg);
}

或 - 简单但略有错误 - 在main之前将变量声明在程序的最顶层:

var a1;

这是一个快速而简单的解决方案;变量将在所有函数中“可见”,并且在任何地方分配新值都可以。它“略微容易出错”,因为具有相同名称(在函数内定义)的 local 变量将有效地“隐藏”原始。因此,如果粗心使用,最终可能会出现如下结构:

var a1 = 1;
a();
alert ("var a1 = "+a1);

function a()
{
    var a1 = 2;
    b();
    alert ("var a1 = "+a1);
}

function b()
{
    alert ("var a1 = "+a1);
}

幸运的是,您使用清晰的描述性变量名称将对您有所帮助。


第80行

if (Folder.name !== /\Resources$/) ...

使用正确的Javascript语法Impro

  1. !==不是有效的比较运算符。使用==(如果等于测试)或===(如果非常等于测试 - 请参阅Does it matter which equals operator (== vs ===) I use in JavaScript comparisons?了解一些细节),如果不等于,则使用!=。< / p>

  2. 您可以将字符串与另一个字符串进行比较,但不能与GREP表达式进行比较。对于您需要/.../"..."的字符串,符号'...'仅为GREP表达式 保留。虽然某些函数可能同时接受GREP和常规字符串,但此测试却没有。

  3. 要在比较中使用GREP字符串,请使用字符串函数match

    if (Folder.name.match(/\\Resources$/)) ...
    

    注意双端括号(一个用于括号if,一个用于match函数)和 double 反斜杠,因为反斜杠是一个'特殊字符'一个GREP字符串。 (它在 Javascript 字符串中也是特殊的,所以无论你打算使用什么,它都可能被称为不正确的语法#4。)


  4. 这会修复一切并使其有效吗?

    未经测试。如果没有这些更正,您的脚本将无效。有了它们,它至少应该某些东西(如果你的逻辑是合理的,你的路径存在,你的输入是正确的,你的Illustrator常量具有正确的名称)。

    暂时,我有可能说它应该有效。


    附录

    需要一些调试才能找出真正的问题。调试策略:在可疑行之前插入alert,显示重要变量的值。跑,等待结果,冲洗,重复。

    首先:传递array作为函数参数似乎是一个不太好的想法。我发现数组被反复复制到自身上(或许这只是我修修补补的结果)。我认为更安全的方法是让getFiles仅返回新添加的文件,并将结果连接到其当前版本(即“in”你打电话给getFiles的例行程序,如果它是getFiles的先前化身并不重要。请参阅(我认为!)关于修改上述“本地”,“全局”和/或“通过”变量的警告。

    function getMyFiles( fold, exp ) {
    //This is line 80//
        if (!fold.name.match (/(\\|\/)Resources$/)) {
    
              var i, temp;
              var array = [];
    
              temp = Folder( fold ).getFiles(); // All files and folders…
    
              for ( i = 0; i < temp.length; i++ ) {
    
                        if ( temp[i] instanceof File && RegExp( exp ).test( temp[i].fsName ) ){
                            //  alert ('path '+fold+', adding '+temp[i]);
                                  array.push( temp[i] );
    
                        };
    
    
                        if ( temp[i] instanceof Folder ) {
    
                                 array = array.concat (getFiles( temp[i], exp ));
    
                        };
    
              };
            //  alert ('array is '+array.length+'\n'+array.join('\n'));
    
              return array;
    
            };
            return [];
    };
    

    您可以像原来的recursiveFolders函数一样调用此函数,但这次不会传递数组,而是分配

    function recursiveFolders( fold, exp )
    {
              var fileList = Array(); // Our matching files…
              fileList = getFiles( fold, exp );
        // alert ('Filelist is '+fileList.length+'\n'+fileList.join ('\n'));
              return fileList;
    
    };
    

    只有当 部分正常工作时,我才会收到您所做的相同错误,根据您的评论“fold.match不是函数”。这需要一分钟左右的时间。事实证明,Javascript解析器是正确的。 最初fold参数为Folder,要获取其名称,您需要fold.name。但请查看您自己的代码:您在递归中使用了自己的参数temp[i].fsName,这是一个String!因此,没有name因此错误。

    首先,我直截了当地使用foldfold.toString转换为always-a-String(适用于文件夹和字符串),但后来我改变主意并使用fold.name来保持一致性,并使用“正确”参数调用getFilestemp[i]而不是temp[i].fsName。现在似乎工作 - 真实。 (稍微有点自信地说。)