htmlgoogle-sheetsgoogle-apps-script

Losing line break when creating HTML Email


I'm using Apps Script to try and create an automated report from Sheets. The email is to pull in a simple table which consists of a header row of working days in the week, then a second row which contains a list of names which are absent on 'x' day. This list contains information condensed from other formulas: =TEXTJOIN(CHAR(10), TRUE, C8:C15).

I've tried following this guide and adapting to my needs: https://www.youtube.com/watch?v=r-g73gCpS4o

I'm almost there and can get the table in my email however the CHAR(10) is lost in the process and destroying the formatting of the table.

I've got the following files. I assume the issue / resolution will have to be in my dataCollector.gs file:

Code.gs

function myFunction() {

// connect to html template
  var html = HtmlService.createTemplateFromFile("email");

// make data collection available to html files
  html.dataCollect = dataCollector(1800699589);

// connect to the template so we can send it in email
  var emailConnect = html.evaluate().getContent();

// send email
  GmailApp.sendEmail(
    ["EXAMPLE EMAIL 1","EXAMPLE EMAIL 2"],
    "Planned Absence - Next Week",
    "Please see .....",
    {htmlBody: emailConnect}
    
    )

}

dataCollector.gs

function dataCollector(sheet_id){

  // access the workbook
    var wb = SpreadsheetApp.getActiveSpreadsheet();

  // access all sheets in workbook
   var sheets = wb.getSheets();

  // loop through sheets
  for(i in sheets){

    // conditional to evaluate the sheet ids

    if(sheets[i].getSheetId() == sheet_id){

      //identify the sheet name
      var sheetName = sheets[i].getSheetName();

    }
  } 

  // access the sheet
    var dataSheet = wb.getSheetByName(sheetName);

  // access the data range
    var dataRange = dataSheet.getRange(1,1,3,5).getDisplayValues()

  // return statement
    return dataRange;

}

email.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
  </head>
  <body>
    <p>Hello, this is email</p>

    <table>
      
      <thead>
        <tr>
          <th><?= dataCollect[1][0] ?></th>
          <th><?= dataCollect[1][1] ?></th>
          <th><?= dataCollect[1][2] ?></th>
          <th><?= dataCollect[1][3] ?></th>
          <th><?= dataCollect[1][4] ?></th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td><?= dataCollect[2][0] ?></td>
          <td><?= dataCollect[2][1] ?></td>
          <td><?= dataCollect[2][2] ?></td>
          <td><?= dataCollect[2][3] ?></td>
          <td><?= dataCollect[2][4] ?></td>
        </tr>

      </tbody>

    </table>

  </body>
</html>

I've tried to use .replace(/n, <br>) on my variable dataRange. Replace does not work unless it is converted to a string.

I tried converting it to a string and then using .replace and I end up losing the entire table and just get two letters showing in my email.

Screenshot of the sheets page to help understand:

Screenshot of the email results:


Solution

  • Adding Break Line in HTML

    Using <br> is correct and I tried using this line of code .replace("\\n", "<br />") to get the result there seems to be an error. I added some lines of code in your Code.gs and Email.html script.

    Sample Data:

    Sample Picture

    Code.gs

    function myFunction() {
    
      // connect to html template
      var html = HtmlService.createTemplateFromFile("email");
    
      // make data collection available to html files
      html.dataCollect = dataCollector(0);
    
      // Sets the days to remove the CHAR(10) in each names in day
      let days = []
    
      // Nested for loop.
      for (let i = 0; i < dataCollector(0)[2].length; i++) {
        if (!dataCollector(0)[2][i]) {
          days.push([])
        } else {
          const tempData = dataCollector(0)[2][i].split("\n");
          let day = [];
          for (let o = 0; o < tempData.length; o++) {
            day.push(tempData[o]);
          }
          days.push(day);
        };
      }
      html.day = days;
    
      // connect to the template so we can send it in email
      var emailConnect = html.evaluate().getContent();
    
      // send email
      GmailApp.sendEmail(
        ["sample@email.com", "sample@email.com"],
        "Planned Absence - Next Week",
        "Please see .....",
        { htmlBody: emailConnect })
    }
    

    email.html

    <!DOCTYPE html>
    <html>
      <head>
        <base target="_top">
        <?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
      </head>
      <body>
        <p>Hello, this is email</p>
    
        <table>
          
          <thead>
            <tr>
              <th><?= dataCollect[1][0] ?></th>
              <th><?= dataCollect[1][1] ?></th>
              <th><?= dataCollect[1][2] ?></th>
              <th><?= dataCollect[1][3] ?></th>
              <th><?= dataCollect[1][4] ?></th>
            </tr>
          </thead>
          <tbody>
         <tr>
            <? for (let i = 0; i < 5; i++) { ?> 
              <td>
                <? for (let o = 0; o < day[i].length; o++) { ?>
                  <?= day[i][o] ?><br>
                <? } ?>
              </td>
            <? } ?>
          </tr>
          </tbody>
        </table>
      </body>
    </html>
    

    Before Result:

    Before Result

    After Result:

    After Result

    Reference: