Export multiple artboards in Adobe Illustrator to png, or pdf
// MultiExporter.js
// Version 0.1
// Version 0.2 Adds PNG and EPS exports
// Version 0.3 Adds support for exporting at different resolutions
//
// Exports Illustrator artboards and/or layers as individual PNG or PDF files
//
// Copyright 2011 Matthew Ericson
// Comments or suggestions to mericson@ericson.net
var docRef = app.activeDocument;
var nyt_png_exporter = {
png_info_lyr: null,
prefix: null,
suffix: null,
base_path: null,
transparency: false,
format: null,
export_type: null,
dlg: null,
prefs_xml: null,
num_to_export: 0,
num_layers: 0,
num_layers_to_export: 0,
num_artboards: 0,
num_artboards_to_export: 0,
init: function() {
// figure out if there is stuff to process
this.num_layers = docRef.layers.length;
this.num_artboards = docRef.artboards.length;
this.num_layers_to_export = this.get_num_layers_to_export();
this.num_artboards_to_export = this.get_num_artboards_to_export();
var parse_success = this.load_prefs();
if (parse_success) {
this.show_dialog();
}
},
load_prefs: function() {
var parse_success = false;
// find existing layers or add new one
try {
this.png_info_lyr = docRef.layers.getByName( 'nyt_exporter_info' );
} catch ( e ) {
this.png_info_lyr = docRef.layers.add();
this.png_info_lyr.name = 'nyt_exporter_info';
var nyt_exporter_info_xml = this.png_info_lyr.textFrames.add();
var saved_data = new XML( '<nyt_prefs></nyt_prefs>' );
saved_data.appendChild( new XML('<nyt_prefix></nyt_prefix>') );
saved_data.appendChild( new XML('<nyt_suffix></nyt_suffix>') );
saved_data.appendChild( new XML('<nyt_base_path>~/Desktop</nyt_base_path>') );
saved_data.appendChild( new XML('<nyt_scaling>100%</nyt_scaling>') );
saved_data.appendChild( new XML('<nyt_transparency>true</nyt_transparency>') );
saved_data.appendChild( new XML('<nyt_format>PNG 24</nyt_format>') );
saved_data.appendChild( new XML('<nyt_export_code>artboards</nyt_export_code>') );
nyt_exporter_info_xml.contents = saved_data.toXMLString();
this.png_info_lyr.printable = false;
this.png_info_lyr.visible = false;
}
// get xml out of the 1 text item on that layer and parse it
if ( this.png_info_lyr.textFrames.length != 1 ) {
Window.alert( 'Please delete the nyt_exporter_info layer and try again.' );
} else {
try {
this.prefs_xml = new XML( this.png_info_lyr.textFrames[0].contents );
this.prefix = this.prefs_xml.nyt_prefix;
this.suffix = this.prefs_xml.nyt_suffix;
this.base_path = this.prefs_xml.nyt_base_path;
this.scaling = this.prefs_xml.nyt_scaling;
this.transparency = this.prefs_xml.nyt_transparency == "true" ? true : false;
this.format = this.prefs_xml.nyt_format;
this.export_code = this.prefs_xml.nyt_export_code;
if ( ! this.prefs_xml.nyt_scaling || this.prefs_xml.nyt_scaling == '' ) {
this.scaling = '100%';
}
parse_success = true;
} catch ( e ) {
Window.alert( 'Please delete the this.png_info_lyr layer and try again.' );
}
}
return parse_success;
},
// dialog display
show_dialog: function() {
// Export dialog
this.dlg = new Window('dialog', 'Export Artboards');
// PANEL to hold options
var msgPnl = this.dlg.add('panel', undefined, 'Export Artboards and/or Layers');
// EXPORT TYPE ROW
var typeGrp = msgPnl.add('group', undefined, '')
typeGrp.oreintation = 'row';
typeGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP]
var typeSt = typeGrp.add('statictext', undefined, 'Export what:');
typeSt.size = [ 100,20 ];
var exportTypeList = typeGrp.add('dropdownlist', undefined, [ 'Artboards (with currently visible layers)', 'Layers (on currently selected artboard)', 'Artboards + Layers' ]);
if ( this.export_code == 'artboards' ) {
exportTypeList.selection = 0;
} else if ( this.export_code == 'layers' ) {
exportTypeList.selection = 1;
} else {
exportTypeList.selection = 2;
}
// PREFIX GRP
var prefixGrp = msgPnl.add('group', undefined, '')
prefixGrp.oreintation = 'row';
prefixGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP]
var prefixSt = prefixGrp.add('statictext', undefined, 'File prefix:');
prefixSt.size = [100,20]
var prefixEt = prefixGrp.add('edittext', undefined, this.prefix);
prefixEt.size = [ 300,20 ];
var prefixGrp = msgPnl.add('group', undefined, '')
prefixGrp.oreintation = 'row';
prefixGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP]
var suffixGrp = msgPnl.add('group', undefined, '')
suffixGrp.oreintation = 'row';
suffixGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP]
var suffixSt = suffixGrp.add('statictext', undefined, 'File suffix:');
suffixSt.size = [100,20]
var suffixEt = suffixGrp.add('edittext', undefined, this.suffix);
suffixEt.size = [ 300,20 ];
var dpiGrp = msgPnl.add('group', undefined, '')
dpiGrp.oreintation = 'row';
dpiGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP]
var dpiSt = dpiGrp.add('statictext', undefined, 'Scaling:');
dpiSt.size = [100,20]
var dpiEt = dpiGrp.add('edittext', undefined, this.scaling);
dpiEt.size = [ 100,20 ];
var dpiSt2 = dpiGrp.add('statictext', undefined, '(Normally 100%; Use 200% for Retina dislay exports)');
dpiSt2.size = [300,20]
// DIR GROUP
var dirGrp = msgPnl.add( 'group', undefined, '')
dirGrp.orientation = 'row'
dirGrp.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP]
var dirSt = dirGrp.add('statictext', undefined, 'Output directory:');
dirSt.size = [ 100,20 ];
var dirEt = dirGrp.add('edittext', undefined, this.base_path);
dirEt.size = [ 300,20 ];
var chooseBtn = dirGrp.add('button', undefined, 'Choose ...' );
chooseBtn.onClick = function() { dirEt.text = Folder.selectDialog(); }
// TRANSPARENCY AND FORMAT ROW
var transPnl = msgPnl.add('group', undefined, '');
transPnl.orientation = 'row'
transPnl.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP]
var formatSt = transPnl.add('statictext', undefined, 'Export format:');
formatSt.size = [ 100,20 ];
var formatList = transPnl.add('dropdownlist', undefined, [ 'PNG 8', 'PNG 24', 'PDF', 'JPG', 'EPS' ]);
formatList.selection = 1;
for ( var i=0; i < formatList.items.length; i++ ) {
if ( nyt_png_exporter.format == formatList.items[i].text ) {
formatList.selection = i;
}
}
transPnl.transparentChk = transPnl.add('checkbox', undefined, 'Transparency');
transPnl.transparentChk.value = this.transparency;
var progBar = msgPnl.add( 'progressbar', undefined, 0, 100 );
progBar.size = [400,10]
var progLabel = msgPnl.add('statictext', undefined, '...' );
progLabel.size = [ 400,20 ];
var btnPnl = this.dlg.add('group', undefined, '');
btnPnl.orientation = 'row'
btnPnl.cancelBtn = btnPnl.add('button', undefined, 'Cancel', {name:'cancel'});
btnPnl.cancelBtn.onClick = function() { nyt_png_exporter.dlg.close() };
// OK button
btnPnl.okBtn = btnPnl.add('button', undefined, 'Export', {name:'ok'});
btnPnl.okBtn.onClick = function() {
nyt_png_exporter.prefix = prefixEt.text;
nyt_png_exporter.suffix = suffixEt.text;
nyt_png_exporter.base_path = dirEt.text;
nyt_png_exporter.transparency = transPnl.transparentChk.value;
nyt_png_exporter.format = formatList.selection.text;
nyt_png_exporter.export_type = exportTypeList.selection.text;
nyt_png_exporter.scaling = parseFloat( dpiEt.text.replace( /\% /, '' ));
if ( nyt_png_exporter.export_type.match( /\+/ )) {
nyt_png_exporter.export_code = 'both';
} else if ( nyt_png_exporter.export_type.match( /^Art/ )) {
nyt_png_exporter.export_code = 'artboards';
} else {
nyt_png_exporter.export_code = 'layers';
}
nyt_png_exporter.run_export();
};
// Export type handler
exportTypeList.onChange = function() {
nyt_png_exporter.export_type = exportTypeList.selection.text;
if ( nyt_png_exporter.export_type.match( /\+/ )) {
nyt_png_exporter.export_code = 'both';
} else if ( nyt_png_exporter.export_type.match( /^Art/ )) {
nyt_png_exporter.export_code = 'artboards';
} else {
nyt_png_exporter.export_code = 'layers';
}
nyt_png_exporter.update_export_desc( progLabel );
};
nyt_png_exporter.update_export_desc( progLabel );
this.dlg.progLabel = progLabel;
this.dlg.progBar = progBar;
this.dlg.show();
},
update_export_desc: function ( progLabel ) {
if ( this.export_code == 'artboards' ) {
progLabel.text = 'Will export ' + this.num_artboards_to_export + ' of ' + this.num_artboards + ' artboards';
this.num_to_export = this.num_artboards_to_export;
} else if ( this.export_code == 'layers' ) {
var current_name = docRef.artboards[ docRef.artboards.getActiveArtboardIndex() ].name;
progLabel.text = 'Will export ' + this.num_layers_to_export + ' of ' + this.num_layers+ ' layers on artboard "' + current_name +'"' ;
this.num_to_export = this.num_layers_to_export;
} else {
this.num_to_export = this.num_layers_to_export * this.num_layers_to_export ;
progLabel.text = 'Will export ' + this.num_to_export + ' files (' + this.num_layers_to_export + ' layers * ' + this.num_artboards_to_export + ' artboards)';
}
},
// run_export function. does the dirty work
run_export: function() {
var num_exported = 0;
var options;
if ( this.format =='PNG 8' ) {
options = new ExportOptionsPNG8();
options.antiAliasing = true;
options.transparency = this.transparency;
options.artBoardClipping = true;
options.horizontalScale = this.scaling;
options.verticalScale = this.scaling;
} else if ( this.format == 'PNG 24' ) {
options = new ExportOptionsPNG24();
options.antiAliasing = true;
options.transparency = this.transparency;
options.artBoardClipping = true;
options.horizontalScale = this.scaling;
options.verticalScale = this.scaling;
} else if ( this.format == 'PDF' ) {
options = new PDFSaveOptions();
options.compatibility = PDFCompatibility.ACROBAT5;
options.generateThumbnails = true;
options.preserveEditability = false;
} else if ( this.format == 'JPG' ) {
options = new ExportOptionsJPEG();
options.antiAliasing = true;
options.artBoardClipping = true;
options.horizontalScale = this.scaling;
options.verticalScale = this.scaling;
} else if ( this.format == 'EPS' ) {
options = new EPSSaveOptions();
options.embedLinkedFiles = true;
options.includeDocumentThumbnails = true;
options.saveMultipleArtboards = true;
}
var starting_artboard = 0;
var num_artboards = docRef.artboards.length;
if ( this.export_code == 'layers' ) {
starting_artboard = docRef.artboards.getActiveArtboardIndex();
num_artboards = starting_artboard + 1;
}
for (var i = starting_artboard; i < num_artboards; i++ ) {
var artboardName = docRef.artboards[i].name;
starting_artboard = docRef.artboards.setActiveArtboardIndex(i);
// Process this artbarod if we're exporting only a single one (layers mode) or if it doesn't have generic name or minus
if ( this.export_code == 'layers' || ! ( artboardName.match( /^artboard/i ) || artboardName.match( /^\-/ ) )) {
// if exporting artboard by artboard, export layers as is
if ( this.export_code == 'artboards' ) {
var base_filename = this.base_path + "/" + this.prefix + artboardName + this.suffix
if ( this.format.match( /^PNG/ )) {
var destFile = new File( base_filename + '.png' );
var export_type = this.format == 'PNG 8' ? ExportType.PNG8 : ExportType.PNG24;
docRef.exportFile(destFile, export_type , options);
} else if ( this.format.match( /^JPG/ )) {
var destFile = new File( base_filename + '.jpg' );
var export_type = ExportType.JPEG;
docRef.exportFile(destFile, export_type , options);
} else if ( this.format.match( /^EPS/ )) {
// dumb. specify a filename, saveAs saves as something else
// so after we save it, we have to rename it to what we want.
var eps_real_filename = base_filename + '_' + artboardName + '.eps'
var destFile = new File( base_filename + '.eps' );
options.artboardRange = (i+1).toString();
docRef.saveAs( destFile, options );
var epsFile = new File ( eps_real_filename );
if ( epsFile.exists ) {
epsFile.copy( base_filename + '.eps' );
epsFile.remove();
}
} else if ( this.format.match( /^PDF/ )) {
var destFile = new File( base_filename + '.pdf' );
options.artboardRange = (i+1).toString();
docRef.saveAs( destFile, options )
}
// export layers as individual files
} else if ( this.export_code == 'layers' || this.export_code = 'both' ) {
for ( var j=0; j < docRef.layers.length; j++ ) {
this.hide_all_layers();
var layer = docRef.layers[j];
var lyr_name = layer.name;
if ( ! ( lyr_name.match( /^\+/ ) || lyr_name.match( /nyt_exporter_info/ ) || lyr_name.match( /^\-/) || lyr_name.match( /^Layer / ) )) {
var base_filename;
if ( this.export_code == 'layers' ) {
base_filename = this.base_path + "/" + this.prefix + lyr_name + this.suffix
} else if ( this.export_code == 'both' ) {
base_filename = this.base_path + "/" + this.prefix + artboardName + '-' + lyr_name + this.suffix
}
layer.visible = true;
if ( this.format.match( /^PNG/ )) {
var destFile = new File( base_filename + '.png' );
var export_type = this.format == 'PNG 8' ? ExportType.PNG8 : ExportType.PNG24;
docRef.exportFile(destFile, export_type , options);
} else if ( this.format.match( /^JPG/ )) {
var destFile = new File( base_filename + '.jpg' );
var export_type = ExportType.JPEG;
docRef.exportFile(destFile, export_type , options);
} else if ( this.format.match( /^EPS/ )) {
var eps_real_filename = base_filename + '_' + artboardName + '.eps'
var destFile = new File( base_filename + '.eps' );
options.artboardRange = (i+1).toString();
docRef.saveAs( destFile, options )
var epsFile = new File ( eps_real_filename );
if ( epsFile.exists ) {
epsFile.copy( base_filename + '.eps' );
epsFile.remove();
}
} else if ( this.format.match( /^PDF/ )) {
var destFile = new File( base_filename + '.pdf' );
options.artboardRange = (i+1).toString();
docRef.saveAs( destFile, options )
}
num_exported++;
this.dlg.progLabel.text = 'Exported ' + num_exported + ' of ' + this.num_to_export;
this.dlg.progBar.value = num_exported / this.num_to_export * 100;
this.dlg.update();
}
}
}
}
}
this.prefs_xml.nyt_base_path = this.base_path;
this.prefs_xml.nyt_scaling = this.scaling;
this.prefs_xml.nyt_prefix = this.prefix;
this.prefs_xml.nyt_suffix = this.suffix;
this.prefs_xml.nyt_transparency = this.transparency;
this.prefs_xml.nyt_format = this.format;
this.prefs_xml.nyt_export_code = this.export_code;
this.png_info_lyr.textFrames[0].contents = this.prefs_xml.toXMLString();
this.dlg.close();
//end run_export
},
hide_all_layers: function() {
var export_count = 0;
var n = docRef.layers.length;
for(var i=0; i<n; ++i) {
layer = docRef.layers[i];
lyr_name = layer.name;
// any layers that start with + are always turned on
if ( lyr_name.match( /^\+/ ) ) {
layer.visible = true;
// any layers that start with -, have default layer name, or named "nyt_exporter_info" are skipped
} else if ( lyr_name.match( /nyt_exporter_info/ ) || lyr_name.match( /^Layer /) || lyr_name.match( /^\-/ ) ){
layer.visible = false;
// everything else we should export
} else {
layer.visible = false;
export_count++;
}
}
return export_count;
},
get_num_layers_to_export: function() {
var num_to_export = 0;
var num_layers = docRef.layers.length;
for(var i=0; i<num_layers; ++i) {
var layer = docRef.layers[i];
var lyr_name = layer.name;
// any layers that start with + are always turned on
if ( lyr_name.match( /^\+/ ) ) {
} else if ( lyr_name.match( /nyt_exporter_info/ ) || lyr_name.match( /^Layer /) || lyr_name.match( /^\-/ ) ){
} else {
num_to_export++;
}
}
return num_to_export;
},
get_num_artboards_to_export: function() {
var num_artboards = docRef.artboards.length;
var num_to_export = 0;
for (var i = 0; i < num_artboards; i++ ) {
var artboardName = docRef.artboards[i].name;
if ( ! ( artboardName.match( /^artboard/i ) || artboardName.match( /^\-/ ) )){
num_to_export++;
}
}
return num_to_export;
},
show_all_layers: function() {
var n = docRef.layers.length;
for(var i=0; i<n; ++i) {
layer = docRef.layers[i];
layer.visible = true;
}
},
};
nyt_png_exporter.init();
This is a reference to Matthew Ericson's article Export Illustrator Layers and/or Artboards as PNGs and PDFs in case something happens to happen to the article, and if I just forget where to find the exporter online.
MultiExporter.js
into /Applications/Adobe\ Illustrator\ CS6/Presets.localized/en_GB/Scripts
All credit goes to Matthew Ericson.