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

Ways to assign a value to an input element in AngularJS without impacting its ngModel

JAVASCRIPT: .directive('search', [function () { return { restrict: 'A', link: function (scope, element, attrs) { attrs.$set('placeholder', 'Word...'); console.log(attrs); ...

D3 Chart: What is the best way to insert images into a node?

Within the jsFiddle demo provided in this query, there is code displayed. I am curious about how I can assign images to each node. var graph = { "nodes":[ {"name":"1","rating":90,"id":2951}, ] } You can access my jsFiddle Demo through this ...

The browser is opting to download the HTML file rather than displaying it

Recently, I set up a server using Node.JS express where I specified the location of an HTML file in the public folder. app.use(express.static(__dirname + '/public')); app.listen(8080); In previous projects, this setup worked seamlessly. However ...

Having trouble getting the Underscore.js template to function correctly with JSON data

Hello there! I have some PHP code $arr = array("title"=>"sample Title", "body"=>"151200"); echo json_encode($arr); The data output is: {"title":"test Title","body":"151200"} When I attempt to use this JSON output in Underscore, I encounte ...

Is it possible to conduct brain.js training sessions multiple times?

Is there a way to specifically train my neural network with new information without having to retrain the entire model, considering the potential performance costs associated with it? The neural network was created using brain.js. ...

When using setState in the onRowSelection event with React's Material-ui tableRow, the selection cannot be properly controlled

Currently, I am working with a material-ui table https://i.stack.imgur.com/JIzLT.png and my goal is to pass selected rows to a function when the DELETE button is clicked. constructor(props) { super(props); this.state = { selecte ...

Adjust width based on value dynamically

I currently have a div that is sized at 250px, housing 3 child divs within it. My goal is for each of these 3 divs to dynamically scale based on their respective values, eventually reaching 100% width. This is the code snippet I am working with: <di ...

Modify KeyboardDatePicker to display the full name of the day and month

Date Selector Hey there, I'm looking to modify the date format from Wed, Apr 7 to Wednesday, April 7. Is there a way to display the full name of the day and month instead of the short abbreviation? ...

Connecting the v-model in a Vue.js child component to update the parent value

I've encountered an issue with a vue component where I'm trying to link a text input in the child template to a variable in the parent using v-model, but it doesn't seem to be working. How can I make this work? Currently, I am using Vue.js ...

The bespoke node package does not have an available export titled

No matter what I do, nothing seems to be effective. I have successfully developed and launched the following module: Index.ts : import ContentIOService from "./IOServices/ContentIOService"; export = { ContentIOService: ContentIOService, } ...

Creating a list that renders responsively using ReactJS

I'm currently working on implementing a responsive search bar that filters through a list of pure components (up to 100 components displayed at once). However, I've noticed there is a slight half-second delay between typing the first letter and s ...

Utilizing jQuery's extend method for object inheritance in a function

I've been experimenting with using jquery extend to simulate inheritance, but it seems that it only works with objects based on my testing. My goal is to achieve the following: var baseDefinition = function() { var self = this; self.calc1 = ...

Submitting data using JavaScript's POST method

I am facing a challenge with posting Array data to an HTTP connector. My data is structured as follows: var data = [{ key:'myKey', keyName:'myKeyName', value:'value', valueName:'valueName' }, { ...

Easiest method for combining elements made in Angular with D3

Exploring various methods to combine D3 and Angular for learning purposes, seeking advice on the approach: The client application is fed a JSON array of nodes and edges from the server. The main component is a graph visualization using D3 force-directed l ...

Event object not being passed to function in UIWebView Javascript onclick event

When inserting HTML dynamically using simple NSStrings and then loading it into a UIWebview, the following approach is taken: [NSString stringWithFormat:@"<div onclick=\"MyClickEvent(e);\"....some more text here"> A function is defined li ...

Implementing an OnChange Event for a Multi-Select Feature in a Vue.js Application

Here is the HTML code for my multi-select input: <select id="invitees_list1" class="form-select" multiple name="multi"> @foreach ($seatedTable->invitees as $invitee) <option> {{ $invitee ...

NextJS 13: Handler Route Request With Invalid JSON Format

Currently utilizing the most recent Next.JS 13 Route Handler to process data submitted by a form. I'm encountering an issue where the new Route Handler isn't working as expected, even though I followed the documentation provided in the link above ...

Kohana ajax causing removal of JQuery Data attributes

Currently, I am developing an application where jquery data is used to pass variables to HTML elements. It has been successful in one part of the site when the data attributes are added to a tr tag. The following code works: <tr class="js-instructions ...

After successfully creating an account, the displayName consistently appears as null

I have a Vue project that utilizes Firebase as the backend. User registration is done using email and password. Below is the method used in Firebase: firebase.auth() .createUserWithEmailAndPassword(this.user.email, this.user.password) . ...

What is the best method for reading CSV files with multiline values in Java?

In an effort to work with multiple JSON files within a CSV file and enhance readability, I am contemplating separating them by ";" and using OpenCSV for parsing. This approach aims to organize JSON data outside the JUnit class for better organization. Is ...