Using Google App Script for Slides to center-align text within a text box

Currently, I am tackling a project that demands the center alignment of text within a textbox on a google slide using a google app script.

The primary objective is to fetch text from a google worksheet and an image from google drive. Subsequently, combine the extracted worksheet text and the image onto a google slide with the same resolution as the image. Once this is done, export the slide to generate a new image and store it in google drive.

I have managed to make the code functional, which is fantastic. However, I'm encountering an error when attempting to align the fetched texts at the center of their respective textboxes. I would greatly appreciate any assistance with this matter.

In implementing this, I made use of the libraries: "DocsServiceApp", "ImgApp," and ensured that the "slidesAPI" is enabled.

`function testinsertTextOnImage() {
const fileId = "1PU6GexJ....tiNkwRum2xYxYP";
const sheetId = "1_5bZsO6YJb8eS....9sgIao9C1uYxt_z2GBDjw";
const columns = ["A", "B", "C"];

const sheet = SpreadsheetApp.openById(sheetId).getSheetByName("Blad1");
const lastRow = sheet.getLastRow();
const texts = columns.map((column) => sheet.getRange(column + lastRow).getValue());

const textProperties = [    
{      
text: texts[0],
left: 500,
top: 475,
width: 880,
height: 80,
fontSize: 150,
fontFamily: "Tangerine",
alignment: SlidesApp.ParagraphAlignment.CENTER,
},
{
text: texts[1],
left: 320,
top: 660,
width: 1000,
height: 120,
fontSize: 30,
fontFamily: "Questrial",
alignment: SlidesApp.ParagraphAlignment.CENTER,
},
{
text: texts[2],
left: 920,
top: 830,
width: 180,
height: 60,
fontSize: 30,
fontFamily: "Questrial",
alignment: SlidesApp.ParagraphAlignment.CENTER
},
];

const file = DriveApp.getFileById(fileId);
const blob = file.getBlob();
const size = ImgApp.getSize(blob);

const presentation = {
title: "Result",
width: { unit: "pixel", size: size.width },
height: { unit: "pixel", size: size.height },
};
const presentationId = DocsServiceApp.createNewSlidesWithPageSize(presentation);

const slides = SlidesApp.openById(presentationId);
const slide = slides.getSlides()[0];
slide.insertImage(blob);
textProperties.forEach(({ text, left, top, width, height, fontSize, fontFamily, alignment }) => {
const textBox = slide.insertTextBox(text, left, top, width, height);
const textStyle = textBox.getText().getTextStyle();
textStyle.setFontSize(fontSize).setFontFamily(fontFamily);
textBox.getText().getParagraphs()[0].setAlignment(alignment);
});
slides.saveAndClose();

const obj = Slides.Presentations.Pages.getThumbnail(
presentationId,
slide.getObjectId(),
{
"thumbnailProperties.thumbnailSize": "LARGE",
"thumbnailProperties.mimeType": "PNG",
}
);
const url = obj.contentUrl.replace(/=s\d+/, "=s" + size.width);
const resultBlob = UrlFetchApp.fetch(url)
.getBlob()
.setName("Result_" + file.getName());
DriveApp.createFile(resultBlob);
DriveApp.getFileById(presentationId).setTrashed(true);
}`

Answer №1

In your code, please make the following modifications.

From:

textBox.getText().getParagraphs()\[0\].setAlignment(alignment);

To:

textBox.getText().getParagraphStyle().setParagraphAlignment(alignment);

Note:

  • I believe that

    const texts = columns.map((column) => sheet.getRange(column + lastRow).getValue());
    could be changed to
    const texts = sheet.getRange(sheet.getLastRow(), 1, 1, 3).getDisplayValues()[0];
    .

  • In your script, it looks like the square brackets `[]` are being escaped. I am concerned about this. Therefore, I would like to include the modified script as shown below.

function testinsertTextOnImage() {
  const fileId = "###";
  const sheetId = "###";

  const columns = ["A", "B", "C"];
  const sheet = SpreadsheetApp.openById(sheetId).getSheetByName("Blad1");
  const lastRow = sheet.getLastRow();
  const texts = sheet.getRange(sheet.getLastRow(), 1, 1, 3).getDisplayValues()[0];
  const textProperties = [
    { text: texts[0], left: 500, top: 475, width: 880, height: 80, fontSize: 150, fontFamily: "Tangerine", alignment: SlidesApp.ParagraphAlignment.CENTER },
    { text: texts[1], left: 320, top: 660, width: 1000, height: 120, fontSize: 30, fontFamily: "Questrial", alignment: SlidesApp.ParagraphAlignment.CENTER },
    { text: texts[2], left: 920, top: 830, width: 180, height: 60, fontSize: 30, fontFamily: "Questrial", alignment: SlidesApp.ParagraphAlignment.CENTER }
  ];
  const file = DriveApp.getFileById(fileId);
  const blob = file.getBlob();
  const size = ImgApp.getSize(blob);
  const presentation = {
    title: "Result",
    width: { unit: "pixel", size: size.width },
    height: { unit: "pixel", size: size.height }
  };
  const presentationId = DocsServiceApp.createNewSlidesWithPageSize(presentation);
  const slides = SlidesApp.openById(presentationId);
  const slide = slides.getSlides()[0];
  slide.insertImage(blob);
  textProperties.forEach(({ text, left, top, width, height, fontSize, fontFamily, alignment }) => {
    const textBox = slide.insertTextBox(text, left, top, width, height);
    const textStyle = textBox.getText().getTextStyle();
    textStyle.setFontSize(fontSize).setFontFamily(fontFamily);
    textBox.getText().getParagraphStyle().setParagraphAlignment(alignment);
  });
  slides.saveAndClose();
  const obj = Slides.Presentations.Pages.getThumbnail(
    presentationId,
    slide.getObjectId(),
    { "thumbnailProperties.thumbnailSize": "LARGE", "thumbnailProperties.mimeType": "PNG" }
  );
  const url = obj.contentUrl.replace(/=s\\d+/, "=s" + size.width);
  const resultBlob = UrlFetchApp.fetch(url).getBlob().setName("Result_" + file.getName());
  DriveApp.createFile(resultBlob);
  DriveApp.getFileById(presentationId).setTrashed(true);
}

  • Based on the code you shared, it seems like you may have used the sample script from my blog post. For more details, you can refer to the post.

Reference:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using SetTimeout with the TextInput component in a React-Native application

Currently, I am working on creating a SearchBar component for my new Android application using React-Native. As a newcomer to React-Native, I created a function called _changeInput() to handle passing text to a local function. Initially, the text pass wor ...

Issue encountered in Angularjs during upgrade process from version 1.2.27 to 1.4.7

Recently, I upgraded my app from using AngularJS 1.2.27 to version 1.4.7, but now I am encountering an error in the AngularJS file. SyntaxError: Unexpected token : (angular.js:12477) at Function (native) at Object.sd. ...

DataStax encountering difficulty locating the JAVA_HOME directory

I recently installed DataStax 4.8.11 on Ubuntu 14.04 in Sparks/Analytics mode using the Installer. The installation went smoothly, however, I encountered an issue with starting the program. Although JAVA is installed and in PATH, Cassandra is unable to loc ...

What are the steps to integrate the socket.io plugin for Node.js into Eclipse?

const io = require('socket.io').listen(80); io.sockets.on('connection', function (socket) { socket.on('set nickname', function (name) { socket.set('nickname', name, function () { socket.emit('ready& ...

Implementing dynamic checkbox values depending on a selection from a dropdown menu in Angular

In my checkbox list, I have various Samsung mobile models and two offers available. $scope.offers = [ { id: "as23456", Store: "samsung", Offer_message:"1500rs off", modalname: "Samsung Galaxy You ...

What could be the reason for this code not waiting for module imports?

Currently, I am facing an issue with dynamically importing modules in a nodejs server running in the development environment. To achieve this, I have implemented an immediately-invoked async function which, in theory, should work perfectly. However, it see ...

Determine whether all elements in the array are false using Array.every()

Below is an example of an array: myArray = {firstValue: false, secondValue: false, thirdValue: true, forthValue: false}; The goal is to determine if every value in the array is false. If that condition is met, then perform a specific action. For instance ...

Sending information from a Java form in JSON format

I'm struggling to send form data in Json format. The code I have isn't working and I'm at a loss for what to do next. Could someone please assist me through this process? .................................................................... ...

Javascript: Accessing a shared variable within the class

Embarking on my JavaScript programming journey filled me with optimism, but today I encountered a challenge that has left me stumped. Within my tutorial project, there exists a class named Model which contains both private and public variables. Of particu ...

How to eliminate spaces while preserving line breaks in a textarea using JS or jQuery

I have been trying to figure out how to remove extra spaces from the beginning and end of lines while keeping the line breaks intact. Here's what I attempted: function removeSpaces(string) { return string.split(' ').join(''); } ...

The issue of VueRouter malfunctioning in history mode within Wordpress

I have integrated Vue into my Wordpress theme, but I am facing an issue with the router when setting mode: 'history'. The site goes blank and even after trying to configure the .htaccess file, nothing seems to work. My project is located in the V ...

Populating a progress bar with a dynamic variable

In my Android app, I have implemented four ProgressBars. Initially, I want all of them to be empty. When a certain variable is updated, I would like for one of the ProgressBars to fill up partially, but only up to a predetermined "goal" that I have set. Fo ...

Creating dynamic forms in Vue using v-for

I'm currently experimenting with creating dynamic form fields using v-for and vuex. My approach involves nesting a v-for inside another v-for. The process of adding new form fields works smoothly, but I encountered an issue when attempting to delete t ...

unable to establish connection due to port error in node.js

While executing node app.js I encountered the following error message info - socket.io started warn - error raised: Error: listen EACCES This snippet shows all the JavaScript code within the application. After running sudo supervisor app.js T ...

Tips on sending information from Express to my HBS template

var Ticket = require('./models/ticket.js'); module.exports = function (app) { app.get('/',function (req, res) { Ticket.find({},function (err, tickets) { if(err) { res.sen ...

I'm experiencing a lack of feedback while implementing jQuery/AJAX with JSONP

Attempting to perform a cross-domain request using jQuery/AJAX, I have the code below; $.ajax({ url: "http://www.cjihrig.com/development/jsonp/jsonp.php?callback=jsonpCallback&message=Hello", crossDomain:true }) .done(function( msg ) { alert( ...

What are the effects of calling callback(false) and callback(true)?

I'm currently diving into a nodejs chat project, and I’m a bit confused about the outcome when callback(false) and callback(true) are triggered in this context... io.sockets.on('connection', function(socket){ socket.on('new user& ...

Stopping the Bootstrap carousel when an input is focused

I have a Bootstrap carousel with a form inside. The carousel is set to pause when hovered over, but I noticed that if the cursor leaves the carousel while typing in the inputs, it goes back to its default cycle of 5000ms. I want the carousel to remain pau ...

Transfer the controller of the parent directive to a directive controller, similar to how it is executed in the "link" function

In the structure of my directives, there is a need for one directive to have functions in its controller so that child elements can interact with it. However, this directive also needs access to its parent directive's controller. I am unsure of how to ...

Search and extract JSON data in MySQL

Currently, I am inputting JSON objects into a MySQL Database and then executing queries on them. Within the database is a table structured as follows: subjects | ----------------------------------------------- ...