Skip to main content
February 8, 2019
Answered

Reading lines on a csv file

  • February 8, 2019
  • 6 replies
  • 2352 views

Need some help if anyone has any answers please

Below is a line I use for reading a cell in an Excel document:

var colHd = "Number", rowHd = "R"+Num, cellCont=excelVal(csvFile,colHd,rowHd);

My Excel document is set up as below:

The only use I have for the "Rows" column is so I can read the cell contents under "Number", so I have the var "Num" counting up so it will look for "R1, R2, etc."

Can I replace the "R"+Num in my code with something else that will just simply read the line number instead of requiring the "Rows" column?

Many Thanks for any help, Bren

This topic has been closed for replies.
Correct answer

Many thanks for all your help everyone

It made me think of different ways of doing this, now I am reading straight from an excel document with just one column filled with the file names, a lot simpler.

My new script is below if anyone would like to use it.

    // Copying Finder files from one folder to another from reading Excel document

        var mySource = Folder.selectDialog ("Choose the Source folder")

        var myTarget = Folder.selectDialog ("Choose the Target folder")

        var excelFile = File.openDialog("Choose Data File (Excel or csv)")

              app.documents.add(); // Create New Document

        var textFrame = app.activeDocument.pages[0].textFrames.add({geometricBounds: [0, 0, 50, 100]}); // y, x, y2, x2

              textFrame.place(excelFile); // Place Excel contents in InDesign

        var txt = textFrame.texts[0];

        var lines = txt.lines;

    // Delete any lone returns on document

        app.findGrepPreferences = null

        app.findGrepPreferences.findWhat = "^\\r"

        app.changeGrepPreferences.changeTo = ""

        app.changeGrep()

    // Work through each line of text

        for (var i = 0; i < lines.length; i++)

             { fileName = lines.contents.replace( RegExp("\\r") , "" ) // Removes the return at the end of the file name read

                try { File (mySource+"/"+fileName).copy(myTarget+"/"+fileName) // Copy to target folder

                      lines.remove(), i-- } catch (er) {} // removes lines from document

              }

        app.documents[0].close(SaveOptions.no); // Close without saving

        alert ("Finished")

6 replies

Correct answer
February 15, 2019

Many thanks for all your help everyone

It made me think of different ways of doing this, now I am reading straight from an excel document with just one column filled with the file names, a lot simpler.

My new script is below if anyone would like to use it.

    // Copying Finder files from one folder to another from reading Excel document

        var mySource = Folder.selectDialog ("Choose the Source folder")

        var myTarget = Folder.selectDialog ("Choose the Target folder")

        var excelFile = File.openDialog("Choose Data File (Excel or csv)")

              app.documents.add(); // Create New Document

        var textFrame = app.activeDocument.pages[0].textFrames.add({geometricBounds: [0, 0, 50, 100]}); // y, x, y2, x2

              textFrame.place(excelFile); // Place Excel contents in InDesign

        var txt = textFrame.texts[0];

        var lines = txt.lines;

    // Delete any lone returns on document

        app.findGrepPreferences = null

        app.findGrepPreferences.findWhat = "^\\r"

        app.changeGrepPreferences.changeTo = ""

        app.changeGrep()

    // Work through each line of text

        for (var i = 0; i < lines.length; i++)

             { fileName = lines.contents.replace( RegExp("\\r") , "" ) // Removes the return at the end of the file name read

                try { File (mySource+"/"+fileName).copy(myTarget+"/"+fileName) // Copy to target folder

                      lines.remove(), i-- } catch (er) {} // removes lines from document

              }

        app.documents[0].close(SaveOptions.no); // Close without saving

        alert ("Finished")

spicyDoge
Known Participant
February 11, 2019

Ok i understand now that the row numbers are part of the file.

In that case, do something like use grep to them out of the line find:^.*,(.*,.*\r)$ or maybe use firstIndexOf(',') to start the slice after the first comma.

February 11, 2019

Here is the full code, it copies files from one place to another (on Mac), you choose a file type to copy (extension type), the folder to search, a folder to copy too and the csv file with the names (minus extension). I use it at work when files are requested so I do not have to manually select hundreds of them. It works great but I just wanted to be able to read the lines without having to have the "Rows" column, it seems unnecessary but I can't find any code to get started.

• The excelVal is to run a function Jongware, was thinking "rowHd = "R"+Num" may be replaced to make it work but judging from the replies it may be a bigger change.

• I am looking at the "directly from Excel" code at the moment Kasyan to see how I can use it.

• It would be very handy to work from xlsx-file instead of a csv file Mike, do you have a working example of that code that I can go from as it's the "//read csv" is where I'm stuck

The full script is below to put it in context, I work on Mac.

    // Copy files to another folder using a csv file list

        alert("To copy files to a folder using a csv file list\r"

                +"Set up a CSV file as the example below:\r"

                +"  Rows     Number\r"

                +"     R1           266\r"

                +"     R2           301\r"

                +"     R3           502\r"

                +"   etc.\r"

                +"(All files to be copied must be in the same folder)"

               ) // Instruction sheet

    //Dialog to set variables

        var fileName = File.openDialog("Select a File with the correct extention to copy") // or var fileName = "_Education_2018.pdf" // File name minus the number

              fileName = fileName.name.replace( RegExp("^.*(?=\\.)") , "" ) // Deletes the number at the start of the name

        var mySource = Folder.selectDialog ("Choose the Source folder") // or var mySource = "~/Desktop/DTop_Artwork/" // Source folder

        var myTarget = Folder.selectDialog ("Choose the Target folder") // or  var myTarget = "~/Desktop/Target/" // Target folder

        var csvFile = File.openDialog("Choose CSV File") // or var csvFile = File("~/Desktop/Book1.csv") // Excel Document location and name

        var errCount = 0 // If empty cells are found in csv file for 5 rows the script finishes

        for (var Num = 1; Num < 1000 ; Num++)

              { var colHd = "Number", rowHd = "R"+Num, cellCont=excelVal(csvFile,colHd,rowHd); // Excel Variable

                 var cellContPad = "0000" // Sets padding for page number

                 var cellCont = (cellContPad.substring(0, cellContPad.length - cellCont.length) + cellCont) //Sets page number with padding

                 if (cellCont == 0000) {errCount = errCount + 1}; if (errCount == 5) {exit()} // exit when 5 empty cells are detected

                 File(mySource+"/"+cellCont+fileName).copy(myTarget+"/"+cellCont+fileName) // Copy to target folder

              }

    // Function for reading the CSV file

        function excelVal(csvFile, X_value, Y_value) {var cLine, cLineArr, xIdx;

                                                                               csvFile.open("r");

                                                                               cLine = "," + csvFile.readln();

                                                                               xIdx = (cLine).search("," + String(X_value) );

                                                                           if (xIdx !=-1) xIdx = cLine.slice(0, xIdx).split(",").length - 1;

                                                                           do { cLineArr = csvFile.readln().split(",");

                                                                                   if (cLineArr[0] == Y_value) {csvFile.close();

                                                                                   return cLineArr[xIdx]; }}

                                                                           while ( !csvFile.eof ) }

spicyDoge
Known Participant
February 10, 2019

>Can I replace the "R"+Num in my code with something else that will just simply read the line number instead of requiring the "Rows" column?

Have you opened the csv file to verify line numbers are present? Unless yours is unique, there is no 'line number' in the file. The line number is obtained as the line-count is incremented with each occurrence of an EOL character.

If you really want the number in an easy way just implement a counter in some manner

var counter = 1;

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

//read csv

//finally increase counter

counter++;

}

Kasyan Servetsky
Braniac
February 10, 2019

Alternatively, you can read it directly from Excel. Why do you need an extra step of exporting an xlsx-file to csv?

Here is a practical example of using the function.

— Kas

Jongware
Braniac
February 9, 2019

Your "excelVal" function does not ring any bells for me -- it is not a standard InDesign function, is it? It seems purposely designed to read data out of any single, uniquely addressable cell. Where did you get hold of it?

If your input data is truly a plain text .CSV file, it might be easier to have your script read it in its entirety, split on '\n' so you have an array of rows, and then split each line on the comma (or any other separator character that you are using) so you get cells. That will create a two-dimensional string in memory, ready to be handled any way you desire.