Copy link to clipboard
Copied
I have some code that works exactly how I'd like it to - however it doesn't work (understandably) when there are commas in the values within the CSV file.
Process I would like to happen: When I select a comp in After Effects and run the script it duplicates the active comp and renames it by concatenating the row's value from the first column to the end of the comp name. Then it looks for text layers in the comp that have the same layer names as the headers in the rest of the CSV row and replace the values if they match. Then it moves to the next row in the CSV and repeats the process.
The following works when there are no commas in the values (Data-NoCommas.csv).
// GET CSV FILE
var _prompt = "Select CSV";
var _filter = "*";
var _multiselect = false;
var csvFilePath = File.openDialog(_prompt, _filter, _multiselect);
// Get the active composition
var comp = app.project.activeItem;
if (!comp || !(comp instanceof CompItem)) {
alert("Please open a composition.");
}
// Read the CSV file
var csvFile = new File(csvFilePath);
csvFile.open("r");
var csvData = csvFile.read();
csvFile.close();
// Parse the CSV data
var lines = csvData.split("\n");
var headers = lines[0].split(",");
var columnIndexes = {};
// Find the column indexes based on the header names
for (var j = 0; j < headers.length; j++) {
columnIndexes[headers[j]] = j;
}
// Iterate over each line in the CSV file (excluding the header line)
for (var k = 1; k < lines.length; k++) {
var cells = lines[k].split(",");
var named = cells[columnIndexes["Name"]];
var rowData = {};
// Store the data for each column
for (var l = 0; l < headers.length; l++) {
var columnName = headers[l];
rowData[columnName] = cells[columnIndexes[columnName]];
}
// Duplicate the active comp
var newComp = comp.duplicate();
newComp.name = comp.name + named;
// Update the text layers in the duplicated comp
var layers = newComp.layers;
for (var m = 1; m <= layers.length; m++) {
var layer = layers[m];
if (layer instanceof TextLayer) {
var layerName = layer.name;
if (rowData.hasOwnProperty(layerName)) {
layer.property("Source Text").setValue(rowData[layerName]);
}
}
}
}I was able to work with someone who was able to help some but now when I run the script it only creates a comp for the last row in the CSV but it does work when the values have commas (Data.csv).
// GET CSV FILE
var _prompt = "Select CSV";
var _filter = "*";
var _multiselect = false;
var csvFilePath = File.openDialog(_prompt, _filter, _multiselect);
// Get the active composition
var comp = app.project.activeItem;
if (!comp || !(comp instanceof CompItem)) {
alert("Please open a composition.");
//return;
}
// Read the CSV file
var csvFile = new File(csvFilePath);
csvFile.open("r");
var csvData = csvFile.read();
csvFile.close();
// Parse the CSV data
var dataArray = parseCsv(csvData);
var headers = dataArray[0];
//var lines = csvData.split("\n");
//var headers = lines[0].split(",");
var columnIndexes = {};
// Find the column indexes based on the header names
for (var j = 0; j < headers.length; j++) {
columnIndexes[headers[j]] = j;
}
// Iterate over each line in the CSV file (excluding the header line)
for (var k = 1; k < dataArray.length; k++) {
var cells = dataArray[k];
var named = cells[columnIndexes["Name"]];
var rowData = {};
}
// Store the data for each column
for (var l = 0; l < headers.length; l++) {
var columnName = headers[l];
rowData[columnName] = cells[columnIndexes[columnName]];
}
// Duplicate the active comp
var newComp = comp.duplicate();
newComp.name = comp.name + named;
// Update the text layers in the duplicated comp
var layers = newComp.layers;
for (var m = 1; m <= layers.length; m++) {
var layer = layers[m];
if (layer instanceof TextLayer) {
var layerName = layer.name;
if (rowData.hasOwnProperty(layerName)) {
layer.property("Source Text").setValue(rowData[layerName]);
}
}
}
function parseCsv(contents, delimiter) {
// contents: String = contents of a CSV file
// delimiter: character that separates columns
// undefined defaults to comma
// Returns: Array [row][column]
var c = ""; // Character at index.
var d = delimiter || ","; // Default to comma.
var index = 0;
var maxIndex = contents.length - 1;
var q = false; // "Are we in quotes?"
var result = []; // Array of rows.
var row = []; // Array of columns.
var rowSum = 0; // Count of row contents.
var v = ""; // Column value.
while (index < contents.length) {
c = contents[index];
if (q) {
// In quotes.
if (c == '"') {
// Found quote; look ahead for another.
if (index < maxIndex && contents[index + 1] == '"') {
// Found another quote means escaped.
// Increment and add to column value.
index++;
v += c;
} else {
// Next character not a quote; last quote not escaped.
q = !q; // Toggle "Are we in quotes?"
}
} else {
// Add character to column value.
v += c;
}
} else {
// Not in quotes.
if (c == '"') {
// Found quote.
q = !q; // Toggle "Are we in quotes?"
} else if (c == "\n" || c == "\r") {
// Reached end of line.
// Test for CRLF.
if (c == "\r" && index < maxIndex) {
if (contents[index + 1] == "\n") {
// Skip trailing newline.
index++;
}
}
// Column and row complete.
row.push(v);
rowSum += v.length;
if (rowSum) {
// Add row only when it has content.
result.push(row);
}
v = "";
row = [];
rowSum = 0;
} else if (c == d) {
// Found delimiter; column complete.
row.push(v);
rowSum += v.length;
v = "";
} else {
// Add character to column value.
v += c;
}
}
if (index == maxIndex) {
// Reached end of data; flush.
row.push(v);
rowSum += v.length;
if (rowSum) {
// Add row only when it has content.
result.push(row);
}
break;
}
index++;
}
return result;
}Anyone out there able to help me out? I'm still fairly new to programming but any help would be greatly appreciated.
Have something to add?
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more