How to import .xlsx to InDesign - javascript

With following code I am trying to import excel file to indesign. I can get data but if in table is more then 3 rows it just continue in line and doesn't create new line.
var doc = app.activeDocument;
// get a text from the XLSX file
var inputFile = File("~/Desktop/test.xlsx");
var temp_frame = doc.textFrames.add();
temp_frame.place(inputFile);
var text = temp_frame.parentStory.contents;
temp_frame.remove();
// make a table from the text
text = text.split('\r');
var table = [];
for (var row = 1; row < text.length; row++) {
table.push(text[row].split('\t'));
}
// loop through the table and make the cards
for (var i = 0; i < table.length; i++) {
var title = table[i][0];
var description = table[i][1];
var price = table[i][2];
var card = make_card(title, description, price);
// move card to some place
card.move([10,10]);
card.move(undefined, [i*75, 0]);
if(i > 2){
card.move([20,10]);
card.move(undefined, [i*75, 20]);
}
}
// the function to create and return a card
function make_card(title, description, price) {
var doc = app.activeDocument;
var title_frame = doc.textFrames.add();
title_frame.geometricBounds = [20, 80, 30, 150];
title_frame.contents = title;
var description_frame = doc.textFrames.add();
description_frame.geometricBounds = [30, 80, 80, 150];
description_frame.contents = description;
var price_frame = doc.textFrames.add();
price_frame.geometricBounds = [80, 80, 100, 150];
price_frame.contents = price;
var group = doc.groups.add([title_frame, description_frame, price_frame]);
return group;
}
My question is how to write code that card doesn't go out of the document but follow on next line and as well as how to add new page automatically when current document is already full.
I tried do do it with following code in loop if index is heigher than 2 move card down. It move it down but it follow in the same line (out of the document) and I also think there is better way how to write it because if excel has 1000 rors and I have to set up this if index condition for every third element ... code will be one mash
if(i > 2){
card.move([20,10]);
card.move(undefined, [i*75, 20]);
}

For this case the simplest straightforward implementation could be like this:
var doc = app.activeDocument;
// get a text from the XLSX file
var inputFile = File("~/Desktop/test.xlsx");
var temp_frame = doc.textFrames.add();
temp_frame.place(inputFile);
var text = temp_frame.parentStory.contents;
temp_frame.remove();
// make a table from the text
var rows = text.split('\r');
var table = [];
for (var i = 1; i < rows.length; i++) table.push(rows[i].split('\t'));
// width and height of cards, gaps, properties of the grid
var card_width = 70;
var card_height = 80;
var gap = 5;
var cols = 2;
var rows = 3;
var cards_per_page = cols * rows;
// calculate and add pages
var cards = table.length;
var pages_to_add = Math.ceil(cards / cards_per_page) - 1;
while(pages_to_add--) doc.pages.add();
var page_num = 0; // start page
var start_point = [10,10]; // start point for a first card on a page
main_loop:
for (var i = 0; i < cards; i++) {
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
// break the loop if there is no more rows in the table
if (table.length == 0) break main_loop;
var table_row = table.shift(); // take a first row from the table
var title = table_row[0];
var description = table_row[1];
var price = table_row[2];
// make a card
var card = make_card(title, description, price);
// send the card to the some page and move at some place
card.move(doc.pages[page_num]);
card.move(start_point);
card.move(undefined, [(card_width + gap)*col, (card_height + gap)*row]);
}
}
if (i > (page_num-1) * cards_per_page) page_num++; // increase the page number
}
// the function to create and return a card
function make_card(title, description, price) {
var doc = app.activeDocument;
var title_frame = doc.textFrames.add();
title_frame.geometricBounds = [20, 80, 30, 150];
title_frame.contents = title;
var description_frame = doc.textFrames.add();
description_frame.geometricBounds = [30, 80, 80, 150];
description_frame.contents = description;
var price_frame = doc.textFrames.add();
price_frame.geometricBounds = [80, 80, 100, 150];
price_frame.contents = price;
var group = doc.groups.add([title_frame, description_frame, price_frame]);
return group;
}

Related

How can I activate slices from guides button's functionality in photoshop scripting using javascript?

I am trying to import an image using columns and rows numbers and then automatically create guides from these numbers and then create slices from these guides. I am using chatGPT to implement this code. It gave me this code but it doesn't work giving me 'TypeError: undefined is not an object' error.(Both options don't work tried separately) I checked out reference and there isn't a property for document object as .slices.But I can't find any code that gives me access to slice the image from reference. Can you help me how can I slice the image using guides. I also need to access to slice info for copy paste options later for my code
// MAKE DOC PIXEL
app.preferences.rulerUnits = Units.PIXELS
app.preferences.typeUnits = TypeUnits.PIXELS
var colCount = 0;
var rowCount = 0;
// OPEN DIALOG
var dlg = new Window('dialog', 'SpriteSheet Importer', [100, 100, 600, 600]);
// INPUT FIELDS FOR NUMBER OF COLUMNS AND ROWS
var colLabel = dlg.add("statictext", [10, 40, 100, 60], "Columns:");
var colInput = dlg.add("edittext", [120, 40, 180, 60], "");
var rowLabel = dlg.add("statictext", [10, 70, 100, 90], "Rows:");
var rowInput = dlg.add("edittext", [120, 70, 180, 90], "");
// IMPORT SPRITESHEET
var openBtn = dlg.add("button", [10, 10, 100, 30], "Import spriteSheet...");
openBtn.onClick = function () {
var file = File.openDialog("Select a file to open:");
if (file) {
var doc = app.open(file);
colCount = Number(colInput.text);
rowCount = Number(rowInput.text);
// ADD VERTICAL GUIDES
var vGuideInterval = doc.width / colCount;
for (var i = 0; i < colCount; i++) {
doc.guides.add(Direction.VERTICAL, vGuideInterval * i);
}
// ADD HORIZONTAL GUIDES
var hGuideInterval = doc.height / rowCount;
for (var i = 0; i < rowCount; i++) {
doc.guides.add(Direction.HORIZONTAL, hGuideInterval * i);
}
// OPTION 1 FOR SLICING
var sliceWidth = doc.width / colCount;
var sliceHeight = doc.height / rowCount;
try {
for (var i = 0; i < colCount; i++) {
for (var j = 0; j < rowCount; j++) {
var x = i * sliceWidth;
var y = j * sliceHeight;
var slice = doc.slices.add(x, y, x + sliceWidth, y + sliceHeight);
}
}
} catch (error) {
alert(error);
}
// OPTION 2 FOR SLICING
try {
doc.slices.createFromGuides();
} catch (error) {
alert(error);
}
dlg.close();
}
}
// ADD CLOSE BUTTON
var closeBtn = dlg.add("button", [320, 10, 410, 30], "CLOSE");
closeBtn.onClick = function () {
dlg.close();
}
// SHOW DIALOG
dlg.show();
``

How to get single value from .xml

I have some xml or excel I want to loop through this document in InDesign script and insert values on defined places
this is excel or xml
this I want to get
I don't have so much scripting experiences so I can only this piece of code
var doc = app.activeDocument;
var myFile = File("~/Desktop/test.xml");
var textExcel = doc.textFrames.add();
textExcel.geometricBounds = [50, 80, 10, 150];
textExcel.place(myFile);
but now how I can get a single value? for example in indesign template first paragraph should look like table --> lorem--> 150
Here is the possible solution:
var doc = app.activeDocument;
// get a text from the XLSX file
var inputFile = File("d:/table.xlsx");
var temp_frame = doc.textFrames.add();
temp_frame.place(inputFile);
var text = temp_frame.parentStory.contents;
temp_frame.remove();
// make a table from the text
var rows = text.split('\r');
var table = [];
for (var i = 1; i < rows.length; i++) table.push(rows[i].split('\t'));
// loop through the table and make the cards
for (var i = 0; i < table.length; i++) {
var title = table[i][0];
var description = table[i][1];
var price = table[i][2];
var card = make_card(title, description, price);
// move the card to some places
card.move([10,10]);
card.move(undefined, [i*75, 0]);
}
// the function to create and return a card
function make_card(title, description, price) {
var doc = app.activeDocument;
var title_frame = doc.textFrames.add();
title_frame.geometricBounds = [20, 80, 30, 150];
title_frame.contents = title;
var description_frame = doc.textFrames.add();
description_frame.geometricBounds = [30, 80, 80, 150];
description_frame.contents = description;
var price_frame = doc.textFrames.add();
price_frame.geometricBounds = [80, 80, 100, 150];
price_frame.contents = price;
// apply styles to the texts in the card
apply_style('title', title_frame);
apply_style('description', description_frame);
apply_style('price', price_frame);
var group = doc.groups.add([title_frame, description_frame, price_frame]);
return group;
}
function apply_style(style_name, frame) {
var doc = app.activeDocument;
try {
var style = doc.paragraphStyles.itemByName(style_name);
frame.paragraphs.everyItem().appliedParagraphStyle = style;
} catch(e) {}
}
This is the XLSX table:
Here is the result layout (3 cards):
It creates cards from XLSX file (applies the styles to the texts inside cards, why not?) and put them on the page of the current document.
You can probably do this with xpath and Document.
https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate
You create a new Document with the xml and you evaluate a xPath.

Change stroke color in seleced group

I try to change stroke color for the group of the path on atrboard. I have document with banch of artboards and icon on each artboards. Each icon contains several groups of the figure. And I have to change that on each artboard. How can I do this with JavaScript in Adobe Illustrator? Thanks.
var doc = app.activeDocument;
var strokeColor = {"red":255, "green":0, "blue":0}
for (i = 0; i < doc.artboards.length; i++) {
doc.artboards.setActiveArtboardIndex(i);
doc.selectObjectsOnActiveArtboard();
var selectedObjects = doc.selection;
var numSelectedObjects = selectedObjects.length;
var docSelection = app.activeDocument.selection;
newRGBColor = new RGBColor ();
newRGBColor.red=strokeColor.red;
newRGBColor.green=strokeColor.green;
newRGBColor.blue=strokeColor.blue;
docSelection.strokeColor =newRGBColor
}
Try:
var doc = app.activeDocument;
var myStrokeColor = new RGBColor();
myStrokeColor.red = 255;
myStrokeColor.green = 0;
myStrokeColor.blue = 0;
for(var i = 0; i < doc.pathItems.length; i++){
doc.pathItems[i].strokeColor = myStrokeColor
}
You may want to take the time to read Adobe's documentation on scripting
To only change the stroke colour of selected items you can use:
var doc = app.activeDocument;
var newRGBColor = new RGBColor();
var mySelection = doc.selection;
newRGBColor.red = 255
newRGBColor.green = 0
newRGBColor.blue = 0
for(var i = 0; i < doc.mySelection; i++){
mySelection[i].strokeColor = newRGBColor
}

Adding duplicate tiles from different arrays PIXI.js

I'm trying to create a slot game;
I have some images that I put into an array
var createSlots = function(){
//setup images as tilingSprites
var slot1 = new PIXI.extras.TilingSprite(t1, 200, 200);
var slot2 = new PIXI.extras.TilingSprite(t2, 200, 200);
var slot3 = new PIXI.extras.TilingSprite(t3, 200, 200);
var slot4 = new PIXI.extras.TilingSprite(t4, 200, 200);
var slot5 = new PIXI.extras.TilingSprite(t5, 200, 200);
var slot6 = new PIXI.extras.TilingSprite(t6, 200, 200);
var slot7 = new PIXI.extras.TilingSprite(t7, 200, 200);
var slot8 = new PIXI.extras.TilingSprite(t8, 200, 200);
var slot9 = new PIXI.extras.TilingSprite(t9, 200, 200);
var slot10 = new PIXI.extras.TilingSprite(t10, 200, 200);
//push slots into array; images, sprites etc.
mainSlotArr.push(slot1, slot2, slot3, slot4, slot5, slot6, slot7, slot8, slot9, slot10);
};
for the moment I have 2 functions (will combine them once I get this working)
createReels1 and createReels2
what they do is copy the mainSlotArray use a shuffle function
Then populate to 2 columns (reels) each (at the moment createReels2 only does one reel)
it then removes the array element from the array it's using
The trouble I'm having is that whatever image tiles are used in createReels2, disappear if they are being used in createReels1 function, e.g if image1.png used in createReels2 and createReels1, then it is not visible in the first 2 reels
createReels functions below (alot of hard coding!)
var createReels1 = function(){
slotArr1 = mainSlotArr.slice();
shuffle(slotArr1);
var counter = 0;
var num = 0
for(var i = 0; i <2; i++){
var slotContainer = new PIXI.Container();
slotContainer.width = 100;
slotContainer.height = 400;
slotContainer.y = 100;
slotContainer.x = i*130;
stage.addChild(slotContainer);
slotContainerArr.push(slotContainer);
for(var j = 0; j < 3; j++){
var slot = slotArr1[j];
var toDel = slotArr1.indexOf(slot);
slot.scale.y = slot.scale.x = .5;
console.log(slot);
var nextY = j*(slot.height/2);
slot.y = nextY;
slotContainerArr[i].addChild(slot);
slotArr1.splice(toDel, 1);//remove from array
}
}
}
var createReels2 = function(){
slotArr2 = mainSlotArr.slice();
shuffle(slotArr2);
var counter = 0;
var num = 0
for(var i = 0; i <1; i++){
var slotContainer = new PIXI.Container();
slotContainer.width = 100;
slotContainer.height = 400;
slotContainer.y = 100;
slotContainer.x = 260;
stage.addChild(slotContainer);
slotContainerArr.push(slotContainer);
for(var j = 0; j < 3; j++){
var slot = slotArr2[j];
var toDel = slotArr2.indexOf(slot);
slot.scale.y = slot.scale.x = .5;
var nextY = j*(slot.height/2);
slot.y = nextY;
slotContainerArr[2].addChild(slot);
slotArr2.splice(toDel, 1);//remove from array
}
}
}
If I understood the code correctly, with quick check:
Sprites can have only one parent. If you check the Sprite object, it actually has a parent property. So slotArr1 and slotArr2 have identical Sprites and that fact doesn't change id you slice them. Then when you are assigning them to different containers, they get moved from one container to the other. You can reuse textures sure, but one Sprite can only have on parent.

JavaScript - Improve my grid search algorithm

I have made my own "GhettoSearch," which is used to find the closest path between 2 given coordinates over a Grid, AKA a "list of coordinates."
The grid is an array like this:
var grid [ [somedata, [x,y,z], somedata], [somedata, [x,y,z], somedata] ]etc..
My start and stop positions is only coordinates, the Z coordinate is irrelevant at the moment.
I can almost get to the end, but some detoures are made because of my cost function.
Here is how the search looks complete: http://i.imgur.com/2ZjQBrh.png
Here is the code I currently use for the search:
var Main = {
GhettoSearch: function(Start, Stop, Grid){
var Pgreed = 1; //From current position to next nearby nodes
var Tgreed = 0.25; //from current position to target node
var Pcost = 0;
var Tcost = 0;
var open = [];
var closed = [];
var aReturn = [];
for (i = 0; i < Grid.length; i++) {
Worldmap.GetNode("Node_" + Grid[i][0]).style.backgroundColor = "#FFFFFF";
Pcost = Heuristics.Distance.Manhattan(Grid[i][1], Start, Pgreed);
Tcost = Heuristics.Distance.Manhattan(Grid[i][1], Stop, Tgreed);
open.push([i, (Pcost + Tcost)]);
}
do {
var TmpData = [0, Infinity];
var TmpForI = null;
for (i = 0; i < open.length; i++) {
if (open[i][1] < TmpData[1]) {
TmpData[0] = open[i][0];
TmpData[1] = open[i][1];
TmpForI = i;
}
}
closed.push(TmpData);
open.splice(TmpForI, 1);
for (i = 0; i < open.length; i++) {
Start = Grid[TmpData[0]][1]; //is now the start for recently closed node
Pcost = Heuristics.Distance.Manhattan(Grid[open[i][0]][1], Start, Pgreed);
Tcost = Heuristics.Distance.Manhattan(Grid[open[i][0]][1], Stop, Tgreed);
open[i] = [open[i][0], (Pcost + Tcost)];
}
} while (open.length > 0);
var PathID = null;
var TmpDist = Infinity;
for (i = 0; i < closed.length; i++) {
var NodeID = Grid[closed[i][0]][0];
var NodeCoords = Grid[closed[i][0]][1];
var NodeCost = closed[i][1];
aReturn.push([NodeID, NodeCoords, NodeCost]);
//var Dist = Heuristics.Distance.Manhattan(NodeCoords, Stop, 1);
if (NodeCost < TmpDist) {
TmpDist = NodeCost;
PathID = i;//Because you will remove the closest cord elese. OR? will u xD
}
}
aReturn.splice(PathID, closed.length);
return aReturn;
}
};
As you can see on the image, while going upwards it goes back and fills the empty spots besides the straight path up, how can I avoid this?
Yes, I have looked at different search aproaches such as BFS and a star, but I have problems implementing this in my own search function

Categories

Resources