Copy link to clipboard
Copied
How do I write a javascript code to open InDesign template, import XML, save and export to pdf?
I mostly need the help with writing the javascript code to open the InDesign file, import some xml that will be randomly coming in and then saving the document.
Copy link to clipboard
Copied
Hi Denise, you can try something like that:
main ()
function main () {
// create a path for a file object
var curFile = File ( "~/Desktop/myTemplate.indt" );
// check if the file exists
if (!curFile.exists) {
alert ( "no template!" );
exit();
}
// open the file
var curDoc = app.open( curFile );
// create a new file object
var inddFile = new File ( curFile.parent + "/myName.indd" );
// save the file
curDoc.save( inddFile );
//XML import
curDoc.importXML( File("~/Desktop/myName.xml") );
// root-element
var root = curDoc.xmlElements[0];
// do your xml stuff, e.g.
var category = root.xmlElements[0]; // for more categories it needs a loop
var product1 = category.xmlElements.itemByName('productname');
product1.placeXML ( curTextFrame1 ); // there must be a textFrame!
// create a new file object
var pdfFile = new File ( curFile.parent + "/myName.pdf" );
// export to pdf
curDoc.exportFile( ExportFormat.PDF_TYPE, pdfFile );
}
Copy link to clipboard
Copied
Thank you. I will try your suggestion.
Would there be a way to make the xml file coming in a variable ???
We would be automating this to receive different named .xml files.....
Copy link to clipboard
Copied
Denise, try it out.
Copy link to clipboard
Copied
I got it to work as is if I point to a "static" file on the desktop...What command would I use if I was going to use it in a workflow that would receive multiple xml files as different names. Basically how do I make
"
//XML import curDoc.importXML( File("~/Desktop/myName.xml") );"
so that it accepts any incoming xml file???
Copy link to clipboard
Copied
If you want the code to run on multiple arbitrary xml files, the first thing you will need to do is store an array of file objects corresponding to the files you want processed. This can be done with an .opendlg selecting for all the xml files you want to run.
var FilePath = new File("thePathToYourUnprocessedXMLfilesFolder");
var xmlArray = FilePath.openDlg("Choose the XML FEED file(s)","*.xml",true);
If you want to eliminate the need for a person to manually select the files, you can also tell the program to just run everything it finds in a given folder:
var theXMLFolder = Folder("pathToFolder");
var xmlArray = theXMLFolder.getFiles(); // The variable is now an array of path objects for the folder contents
Once you have an array of the xml files you want to run, you will need to nest your code in a for loop:
for(var arrayIndex = 0; arrayIndex < xmlArray.length; arrayIndex++){
// Do stuff with the xml data
// If it's a lot of files, you might want to automatically save/close the document after you are finished with it
}
Just call all your code inside that loop replacing the static file path with: File (xmlArray[arrayIndex])
Good practice bonus:
I recommend also checking that the path object is an instance of a file with an xml extension so that if someone drops a folder or a text document in your hot folder, the system just ignores it. There is no property built in for the later check but this prototype placed at the top of your script should do the trick:
// Add a file object command to display the file extension
if (File.prototype.fileExt == null) File.prototype.fileExt = function(){return this.name.replace(/^.*\./,'')};
so the for loop code should now look something like this:
for(var arrayIndex = 0; arrayIndex < xmlArray.length; arrayIndex++)
{
if (xmlArray[arrayIndex] instanceof File) // Ignore folders
{
if(xmlArray[arrayIndex].fileExt () == "xml") // Ignore files that are not xml files
{
// Do stuff with the xml data
// If it's a lot of files, you might want to automatically save/close the document after you are finished with it
}
}
}
This answer is probably too late for you but hope it helps someone in the long run.
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more