Right alignment of text in table cell - aspose

I populate word table like this (code below). And I would like to insert text in variable run aligned to the right. I have tried many things but nothing works. Can you please help?
var entryTable = bm.getBookmarkStart().getAncestor(com.aspose.words.NodeType.TABLE);
if (entryTable != null) {
var myArray = ['A', 'B', 'C', 'D', 'E'];
var passes = myArray.length;
var index = 1;
while (...(id, myArray[0]+index)!="")
{
var cRow = entryTable.getLastRow().deepClone(true);
for (var j = 0; j < passes; j++) {
var run = cRow.getCells().get(j).getFirstParagraph().getRuns().get(0).deepClone(true);
var key = ...(id, myArray[j]+index);
run.setText(key);
cRow.getCells().get(j).removeAllChildren();
cRow.getCells().get(j).ensureMinimum();
cRow.getCells().get(j).getParagraphs().get(0).appendChild(run);
}
index++;
entryTable.appendChild(cRow);
}
entryTable.getRows().get(1).remove();
} else {
log.warn(LOG_PREFIX + "...");
}

You can use the following code to right-align all Paragraphs in a Table Cell.
Document doc = new Document("D:\\temp\\table.docx");
Table table = doc.getFirstSection().getBody().getTables().get(0);
for (Paragraph para : (Iterable<Paragraph>) table.getLastRow().getLastCell().getParagraphs())
{
para.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT);
}
doc.save("D:\\Temp\\18.11.docx");
Hope, this helps. I work with Aspose as Developer Evangelist.

Related

Multiple Dropdownlist from another spreadsheet with more than 500 items in each

Hello and thanks in advance for your help,
I find many other topics about this, but I did not find answers to my problem, so here I am.
My goal is to automaticly create dropdow lists in a board (between 50-100 drop down list), according to a word in another column. The data should be in another spreadsheet, and most of the dropdown list could go around 600-700 items.
Please check in picture below for more explainations :
board picture
The dropdown list 1 and 2 are created in column G and H if it does find a sheet name in the first word of the column F "designation". If you pick an item of colum G "Libellés", it makes a Vlookup for column "MP" and price in the designated sheet. Same if you pick an item in of column "MP", it makes a Vlookup in "Libellés" and "price" to match.
This is working fine when all sheets are in the same spreadsheet, but I can't find a way to make it work when all data sheets are in another spreadsheet. The spreadsheet with the code will be copy many times (200+ each year), so I want to put the database sheets (15000+lignes x 5 columns) in only one spreadsheet that feeds all others "small" spreadsheets when we open those.
I tryed many options :
requireValueInList : This is not working, some lists are 600-700 items, not working with big lists like this.
list from a range : Ranges are too big, and I have around 50-100 dropdown list of 100-700 items, this is too much, program stops before the end (and I have a good computer, which is not the case of most of my colleagues), so this is not a solution, or I am doing it wrong.
requireValueInRange : This is what I am using to make it run when everything is on the same spreadsheet, but can't use it if datas are on another spreadsheet.
Is there a way to get around requireValueInRange limitation? This is the first time I use google app script so please don't judge too harshly.
here is the code, it is working fine when all data sheets are in the same sspreadsheet as the target sheet for drop dow list:
function onOpen(e) {
// sss for source spreadsheet where I have all datas, and tss for target spreadsheet where I want my lists to be created
var sss1 = spreadsheetApp.openById('blahblah');
var ssh1 = sss1.getSheetByName('Emballages');
var tss = SpreadsheetApp.getActiveSpreadsheet();
var tsh = tss.getActiveSheet();
var tsh1 = tss.getSheetByName('Fiche_eclate_CS');
// The below part is to update 2 lists, using datas from the sheet "emballages" in the source spreadsheet, all working fine except data validation rule, won't accept arguments
var sheet = tss.getSheets()[0];
var column = sheet.getRange("F:F").getValues();
var prow;
for (var i = 0; i < column.length; i++){
if (column[i][0] === "Packaging :") {
prow = i+1;
break;
}
}
var emblrow = ssh1.getRange('B:B').getLastRow();
var cel1D = tsh1.getRange(prow,7);
// This is where I have problems. The call ('B2:B'+ emblrow) is not accepted. I can't use this as data validation on another spreadsheet.
var cel2D = ssh1.getRange('B2:B'+ emblrow);
var ruleD = SpreadsheetApp.newDataValidation().requireValueInRange(cel2D).build();
cel1D.setDataValidation(ruleD);
var cel1M = tsh1.getRange(prow,8);
// Same problem here. The call ('A2:A'+ emblrow) is not accepted.
var cel2M = ssh1.getRange('A2:A'+ emblrow );
var ruleM = SpreadsheetApp.newDataValidation().requireValueInRange(cel2M).build();
cel1M.setDataValidation(ruleM);
// The below part is to update many lists, using datas from one sheet in the source spreadsheet. To find the good sheet in the other spreadsheet, I use the split function. This part is working fine. I only have problems with data validation rules, same as above.
var ui = SpreadsheetApp.getUi();
var button = ui.alert("Voulez vous mettre à jour toutes les listes de la feuille ?",ui.ButtonSet.YES_NO);
if (button == ui.Button.YES) {
var anchhrow;
var anchbrow;
var column1 = tsh1.getRange("B:B").getValues();
for (var i = 0; i < column1.length; i++){
if (column1[i][0] === "Anchor-haut") {
anchhrow = i+3;
break;
}
}
for (var i = 0; i < column1.length; i++){
if (column1[i][0] === "Anchor-bas") {
anchbrow = i;
break;
}
}
var rangeH1 = tsh.getRange('H'+anchhrow +':H'+anchbrow).getValues();
var range = tsh.getRange('H'+anchhrow +':H'+anchbrow);
var lrowH = rangeH1.length;
for (var k=0; k<lrowH; k++){
var rown = anchhrow + k;
var testrng = sheet.getRange("F" + rown);
if ( testrng == "" ) {
}
else {
var name = nom(tsh,rown);
var ssh3 = sss1.getSheetByName(name);
if (ssh3 == null){
}
else {
var flrow = ssh3.getRange('B2:B').getLastRow();
var rng1D = tsh1.getRange(k+anchhrow,7);
// same issu, can't use ('B2:B'+ flrow)for data validation
var rng2D = ssh3.getRange('B2:B'+ flrow);
var ruleD =
SpreadsheetApp.newDataValidation().requireValueInRange(rng2D).build();
rng1D.setDataValidation(ruleD);
var rng1M = tsh1.getRange(k+anchhrow,8);
// same here, can't use ('A2:A'+ flrow)for data validation
var rng2M = ssh3.getRange('A2:A'+ flrow );
var ruleM = SpreadsheetApp.newDataValidation().requireValueInRange(rng2M).build();
rng1M.setDataValidation(ruleM);
}
}
}
function nom(sheet,row){
var word = [{}];
var rng = sheet.getRange("F" + row);
var word = rng.getValue().split(" ");
Logger.log(word);
return word[0];
}
}
else {
}
// This part is where I control prices once all lists are updated, this is working fine.
var ui = SpreadsheetApp.getUi();
var button = ui.alert("Les listes ont été mises à jour. Voulez vous mettre à jour les prix ?",ui.ButtonSet.YES_NO);
if (button == ui.Button.YES) {
for(var j=0;j<lrowH; j++){
var cellI1 = tsh.getRange(j+anchhrow,8).getValue();
if (cellI1 == "") {
}
else {
var cellI2 = vlookup(ssh2,1,3,cellI1);
tsh.getRange(j+anchhrow,9).setValue(cellI2);
function vlookup(sheet, column, index, value) {
var lastRow=sheet.getLastRow();
var data=sheet.getRange(1,column,lastRow,column+index).getValues();
for(i=0;i<data.length;++i){
if (data[i][0]==value){
return data[i][index];
}
}
}
}
}
}
else {
}
Browser.msgBox ("MAJ feuille terminée");
}
Feel free to ask questions if there are stuffs you don't understand or if you need more details.
Thanks in advance,
The main issue you are encountering is due to the fact that you are calling the getActiveSpreadsheet method instead of the openById(id).
However, assuming that you have the same names for the sheets but they're just in different spreadsheets and you want to keep on using the requireValueInRange method, I suggest you add the following lines to your code:
Code
function createDataValidation() {
let spreadsheetIds = ['SS_1_ID', 'SS_2_ID', ...];
for (let i=0; i<spreadsheetIds.length; i++) {
var tss = SpreadsheetApp.openById(spreadsheetIds[i]);
var tsh = tss.getActiveSheet();
var tsh1 = tss.getSheetByName('Fiche_eclate_CS');
// the rest of your code
}
}
The code above is looping through all the spreadsheets - this is done by storing all the ids of the spreadsheets you want to use in the spreadsheetIds variable and afterwards, by using a for loop, is accessing each one of them and using the code you already have.
Reference
Apps Script SpreadsheetApp Class - openById.
I suggest
function betweenSpreadsheets() {
let localSs = SpreadsheetApp.getActiveSpreadsheet();
let distSsUrl = 'https://docs.google.com/spreadsheets/d/1H-Zh blah blah KHP7x8/edit?usp=sharing';
let distSsId = '1H-Zh blah blah KHP7x8';
let distSs1 = SpreadsheetApp.openById(distSsId)
let distSs2 = SpreadsheetApp.openByUrl(distSsUrl)
}
Then proceed as if the sheets were in the same spreadsheet.

Problem with If/Then code with Google Sheet Script

Someone please help.
I am trying to create a simple script which records button presses in order.
I have:
function P1Buzzer() {
var sheet = SpreadsheetApp.getActiveSheet();
var row = 6;
var col = 1;
var Name = sheet.getRange(row, col).getValue();
var sheet = SpreadsheetApp.getActiveSheet();
var row = 192;
var col = 1;
var AnswerPosition = sheet.getRange(row, col).getValue();
if (AnswerPosition = 1) {
sheet.getRange(199, 1).setValue(Name);
var AnswerPosition = AnswerPosition + 1
sheet.getRange(192, 1).setValue(AnswerPosition);
}
if (AnswerPosition = 2) {
sheet.getRange(200, 1).setValue(Name);
var AnswerPosition = AnswerPosition + 1
sheet.getRange(192, 1).setValue(AnswerPosition);
}
}
The problem I have is that when I run the script it does both the commands, ignoring the if command.
Any ideas?
First, you are setting the value to 1 by using = instead of ==. Second, if it was 1, you add one to it and then check to see if it is 2. I'll bet it is!
if (AnswerPosition == 1) {
sheet.getRange(199, 1).setValue(Name);
var AnswerPosition = AnswerPosition + 1
sheet.getRange(192, 1).setValue(AnswerPosition);
} else if (AnswerPosition == 2) {
...

How can one conditionally delete rows in bulk

I am trying to delete rows in bulk which has values as web links starting with "www."
There are 1000+ such entries in my Google Spreadsheet which starts with "https://www." and "www."
I wish to delete only those starting with "www." and I tried this code in GAS.I'm pretty naive to GAS.
Unfortunately I'm missing out on some part of code due to which it is deleting all instances which has "www."
Below I have pasted the code snippet:
function deleteRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var toDelete = [];
var re = new RegExp('www.');
for (var row = 0; row < values.length; row++) {
for(var column = 0;column<values[row].length;column++){
if (re.exec(values[row][column])){
toDelete.push(row);
}
}
}
for(var deleteRow = toDelete.length-1; deleteRow >= 0;deleteRow--){
sheet.deleteRow(toDelete[deleteRow]+1);
}
Also I did try out this which worked partially after tweaking.
Delete row in Google Sheets if certain "word" is found in cell

Passing Multiple Values

I have a visualization table that has an event listener on select.
The need: I want the user to be able to delete documents on the google drive without having to leave the webpage
The set up: I added a button so that when clicked, I get a confirm alert box that includes the value. Once I click OK, it runs the scripts from the client-side with an event handler. This works perfectly!
The problem: I can move one document at a time but if I need to move 20+ documents it gets really tedious to click rows one after the other. Is it possible to pass multiple values to the successhandler?
google.visualization.events.addListener(archiveChart.getChart(), 'select', function () {
$("#docArchive").on("click", function() {
var selection = archiveChart.getChart().getSelection();
var dt = archiveChart.getDataTable();
if (selection.length > 0) {
var item = selection[0];
var docurl = dt.getValue(item.row, 2);
var docname = dt.getValue(item.row, 1);
var folder = dt.getValue(item.row, 4);
if(confirm("Are you sure you want to archive " + docname + "?") == true) {
archiveChart.getChart().setSelection([]);
return google.script.run.withSuccessHandler(onSuccessArchive).withFailureHandler(function(err) {
alert(err);
}).archiveDoc(docurl,folder);
} else {
archiveChart.getChart().setSelection([]);
}
}});
})
I feel like I might need to add this:
for (var i = 0; i < selection.length; i++) {
var item = selection[i];
I'm struggling a little with understanding what I might need to change (still learning). Any help or guidance is appreciated!
recommend confirming once, for all documents
then loop the selection to archive each document
google.visualization.events.addListener(archiveChart.getChart(), 'select', function () {
$("#docArchive").on("click", function() {
var selection = archiveChart.getChart().getSelection();
var dt = archiveChart.getDataTable();
var docNames = selection.map(function (item) {
return dt.getValue(item.row, 1);
}).join('\n');
if (selection.length > 0) {
if(confirm("Are you sure you want to archive the following document(s)?\n" + docNames) == true) {
for (var i = 0; i < selection.length; i++) {
var item = selection[i];
var docurl = dt.getValue(item.row, 2);
var docname = dt.getValue(item.row, 1);
var folder = dt.getValue(item.row, 4);
return google.script.run.withSuccessHandler(onSuccessArchive).withFailureHandler(function(err) {
alert(err);
}).archiveDoc(docurl, folder);
}
}
archiveChart.getChart().setSelection([]);
}
});
});

How can I calcuate wrapping text height in a famo.us surface?

Within famo.us, I want to place a variable-length wrapping title near the top then have images etc follow. All items must be their own surface as some have click events and animations but all the positioning must be super fast to calculate and place based on the text height and of course must avoid DOM access for the 60fps. This must happen for a series of mini-posts, streaming real time and for infinite scroll.
So far, I came up with an approach that works using an ascii character map to pixel width load off screen on init if isn't already in localStorage. It uses jquery to do the sizing for each character, then determine line height by checking a breaking word and the height of that box. After that I use this map for calculations on the fly so I don't touch DOM again. It seems to work fine but is completely dependent on knowing the style of font going to be used in a very specific way. For each new style, I would have to have a different mapping which sucks.
Is there another approach that is more built in to famo.us?
I'm answering my own question because its frankly been awhile, the new framework is going to come out June 22nd of this month (at the time of the this writing). Just going to put how I'm doing this currently which is the way I described above.
Here's the 0.3.5 way of Famou.us to do this.
This is in a file "utils/lines.js" I whipped up. Hack, yes. Works, yes.
define(function(require) {
'use strict';
var $ = require('jquery');
var cache = require('utils/cache');
function getLineInfo(id) {
var cacheKey = 'lineInfo_' + id;
var savedLineInfo = cache.get(cacheKey);
if (savedLineInfo)
return savedLineInfo;
var charStart = 32; // space
var charEnd = 126; // ~
var $charDump = $('<div>', { id: id });
$('body').append($charDump);
for (var i = charStart; i <= charEnd; i++)
$charDump.append($('<div>', { class: 'char', css: { top: (i-32) * 20 } }).html('&#' + i));
var charMap = {};
$charDump.find('.char').each(function() {
var $this = $(this);
var char = $this.text().charCodeAt(0);
var w = $this.width();
charMap[char] = w;
});
$charDump.html('<div class="line">abc<br>123<br>456</div>');
var lineHeight = $charDump.height() / 3;
$charDump.remove();
savedLineInfo = {
lineHeight: lineHeight,
charMap: charMap
};
cache.set(cacheKey, savedLineInfo);
return savedLineInfo;
}
function getLines(text, width, id, maxLines) {
var lineInfo = getLineInfo(id);
var cleaned = $.trim(text.replace(/\s+/gm, ' '));
var words = cleaned.split(' ');
var lines = 1;
var lineWidth = 0;
var spaceLength = lineInfo.charMap[32];
var allLines = '';
words.forEach(function(word) {
var wordLength = 0;
word.split('').forEach(function(char) {
var charLength = lineInfo.charMap[char.charCodeAt(0)];
if (!charLength)
charLength = spaceLength;
wordLength += charLength;
});
if (lineWidth + wordLength + spaceLength <= width) {
lineWidth += wordLength + spaceLength;
if (maxLines)
allLines += word + ' ';
}
else {
lineWidth = wordLength;
if (maxLines && lines <= maxLines)
allLines += word + ' ';
else if (maxLines)
return {text: allLines.substr(0, allLines.length - 3) + '...', lines: lines};
lines++;
}
});
if (maxLines)
return {text: allLines, lines: lines};
return lines;
}
function getTextHeight(text, width, id, maxLines) {
var lineInfo = getLineInfo(id);
var info;
if (maxLines) {
info = getLines(text, width, id, maxLines);
info.height = lineInfo.lineHeight * info.lines;
return info;
}
return lineInfo.lineHeight * getLines(text, width, id);
}
return {
getLines: getLines,
getLineInfo: getLineInfo,
getTextHeight: getTextHeight
};
});