Skip to main content
Participant
September 9, 2010
Answered

Help importing catalog data from a text file (import from csv, tab-delimited, excel)

  • September 9, 2010
  • 1 reply
  • 1530 views

Hi All-

I've been banging my head on this one for a couple of days now. It seems like something that's probably been done before and shouldn't be all that difficult, but I've found little if any help in Adobe's documentation (and many many google searchs).

I have a 100-page retail catalog with about 1000 products in InDesign CS5. I have an excel spreadsheet with this year's product names, prices, and updated descriptions. Normally, we would go through one-by-one and cut and paste. This year I thought I'd try to bypass that step. There are plugins that do this, but they're not cheap, and we're not big. Upgrading to CS5 from CS2 was a big investment in and of itself.

Here's an example of the data (I'm using a pipe character as the delimiter):

28392779|3627|super top|Get a handle on fun. Wind the cord around the spindle and let 'er rip.|6½” long
|$10

So... standard excel file exported to any delimited format (I actually use OpenOffice to do the export to avoid the problem of excel quoting damn near *everything*). In the InDesign file we have a text pane for each name, description and price grouped together. The group has a script label of the product ID and each field within the group is labeled accordingly (name, id, description). So, group: 3627, item: description (or name or price).

Pseudo code:

  Open file

  Parse data into an array

  Step through InDesign file group by group

  Check group script label, Look it up in array, Assign values to fields

Easy right?

I'm not new to javascript, but it's not my strongest language. With this effort I've had problems as simple as syntax for identifying groups by their label. Anyway, here's the code (it ain't pretty as the only way I could even get it to run was to step through the data array line by line and then step through the entire InDesign file for each data line. And, yes, it takes about an hour to run -- but it *does* run):

var myDocument = app.activeDocument;

var datafile =  File("/Users/reddfoxx/Desktop/2010Sept8CatDesc.csv");
datafile.open("r");
  
var data = datafile.read()
  
data = data.split("\n");


// the data array is 0 indexed
//  field 0 is the internal ID
//  field 1 is the product ID
//  field 2 is the product name
//  field 3 is the description
//  field 4 are the dimensions
//  field 5 is the price

   for(x = 0; x < data.length; x++){
      
      data = data.split("|");

      
      for(var z = 0; z < myDocument.groups.count(); z++) {
          if(myDocument.groups.item(z).label == data[1]) {
               myGroup = myDocument.groups.item(z);
              
               for(var y = 0; y < myGroup.textFrames.count(); y++) {
                  if(myGroup.textFrames.item(y).label == "name")
                  {
                       myGroup.textFrames.item(y).contents = data[2];

                  }
             
                  if(myGroup.textFrames.item(y).label == "description")
                  {
                       myGroup.textFrames.item(y).contents = data[3];
                  }
             
                  if(myGroup.textFrames.item(y).label == "dimensions")
                  {
                       myGroup.textFrames.item(y).contents = data[4];
                  }
             
                  if(myGroup.textFrames.item(y).label == "price")
                  {
                       myGroup.textFrames.item(y).contents = data[5];
                  }


              }
          }   
      }
}

For anyone who's unfamiliar with groups and scripting, unfortunately, you can't address the text frames inside a group without using the group. At least, that's what I understand.

Any help would be much appreciated. Even just figuring out how to address a particular group in the document, so that I don't have to step through the entire file and do a compare for every item would be a vast improvement.

Thanks in advance.

-Redd

Correct answer tomaxxi

Hey!

You have nice little problem here

Well, unfortunately, InDesign CS5 is little heavy on script labels, there were some changes and stuff. In CS4 and before, when you call pageItem.item(myItemName), you would get script label, but in CS5 it was changed, and now you get name of item that can be found in Layers palette. Now, you can easily copy all script labels, to new place, and then it would be easy to access items by item name.

This will copy all current script labels to item name:

for(var i = 0; i < app.activeDocument.allPageItems.length; i++)
  app.activeDocument.allPageItems.name = app.activeDocument.allPageItems.label;

Now, when you have all names set up, you can access them like this:

app.activeDocument.groups.item(data[1]).textFrames.item("name").contents = data[2];

app.activeDocument.groups.item(data[1]).textFrames.item("description").contents = data[3];
app.activeDocument.groups.item(data[1]).textFrames.item("dimensions").contents = data[4];
app.activeDocument.groups.item(data[1]).textFrames.item("price").contents = data[5];

Hope it helps!

--

tomaxxi

http://indisnip.wordpress.com/

1 reply

tomaxxi
tomaxxiCorrect answer
Inspiring
September 9, 2010

Hey!

You have nice little problem here

Well, unfortunately, InDesign CS5 is little heavy on script labels, there were some changes and stuff. In CS4 and before, when you call pageItem.item(myItemName), you would get script label, but in CS5 it was changed, and now you get name of item that can be found in Layers palette. Now, you can easily copy all script labels, to new place, and then it would be easy to access items by item name.

This will copy all current script labels to item name:

for(var i = 0; i < app.activeDocument.allPageItems.length; i++)
  app.activeDocument.allPageItems.name = app.activeDocument.allPageItems.label;

Now, when you have all names set up, you can access them like this:

app.activeDocument.groups.item(data[1]).textFrames.item("name").contents = data[2];

app.activeDocument.groups.item(data[1]).textFrames.item("description").contents = data[3];
app.activeDocument.groups.item(data[1]).textFrames.item("dimensions").contents = data[4];
app.activeDocument.groups.item(data[1]).textFrames.item("price").contents = data[5];

Hope it helps!

--

tomaxxi

http://indisnip.wordpress.com/

Participant
September 14, 2010

tomaxxi-

Thank you so much. This worked and I took it another couple of steps beyond this. I'll post my code in a couple of days (after the catalog gets off to the printer).

Thanks again.

-Redd

tomaxxi
Inspiring
September 14, 2010

You are welcome!

Glad it worked!

Looking forward to see the script

--

tomaxxi

http://indisnip.wordpress.com/