2

I am automating the creation of a document using google apps script. This script runs in a google sheet and creates a document with text, tables, references, and so on. The document has approx. 10 pages and a section that is the same in every document.

After the word “Urgência” I want to insert a footnote index (with the number 1) and the respective text at the bottom of the page, something like this: “4.8 Urgência¹ (conforme definição….”

This is a snippet of the middle of my code:

     var doc = DocumentApp.getActiveDocument();
     var id = doc.getId();
     var corpo = doc.getBody();

     var texto = corpo.appendParagraph("\n\n\n\n\nNota Técnica*" + "\n\n" + "Processo" + "\n" + numero_processo).setFontSize(30).setAlignment(DocumentApp.HorizontalAlignment.CENTER).setFontFamily("Lato");
      var texto = corpo.appendParagraph("\nData de submissão: XX/XX/2022").setFontSize(14).setAlignment(DocumentApp.HorizontalAlignment.RIGHT).setFontFamily("Lato").setBold(true);
      // Cria uma página nova
      var texto = corpo.appendParagraph("\n\n\n\n\n\n\n\n\n\n\n\n*Avaliação técnica produzida no âmbito institucional do TelessaúdeRS-UFRGS, estabelecido como Núcleo de Apoio Técnico da Justiça Federal do Rio Grande do Sul (NAT-Jus/JFRS) pelo Contrato n° 33/2019 firmado pela JFRS, UFRGS e FAURGS. Elaboração por profissionais da saúde, baseada em evidências científicas de eficácia, acurácia, efetividade, segurança e custo-efetividade, conforme termos contratuais e o disposto na Resolução Nº 388/2021 do CNJ e no § 2º do art. 156 do CPC, Lei nº 13.105/2015").setFontSize(10).setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY).setFontFamily("Arial").setBold(false);
      corpo.appendPageBreak();

      // Adiciona item 1 do processo:
      var titulo = corpo.appendParagraph("1\tDados do processo");
      titulo.setHeading(DocumentApp.ParagraphHeading.HEADING1).setFontSize(12).setFontFamily("Arial").setBold(true);
      var texto = corpo.appendParagraph("1.1\tNúmero do Processo:  " + numero_processo);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("1.2\tVara: " + " " + vara);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");;

      // Adiciona item 2 do processo:
      var titulo = corpo.appendParagraph("2\tDados do Paciente");
      titulo.setHeading(DocumentApp.ParagraphHeading.HEADING1).setFontSize(12).setFontFamily("Arial").setBold(true);
      var texto = corpo.appendParagraph("2.1\tCartão Nacional da Saúde: " + cns);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("2.2\tCPF: " + cpf);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("2.3\tNome: " + nome_paciente);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("2.4\tData de Nascimento: " + data_nascimento);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("2.5\tIdade: " + idade);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("2.6\tSexo: " + sexo);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("2.7\tNome da mãe: " + nome_mae);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("2.8\tMunicípio de residência/UF: " + residencia);
     texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");

      // Adiciona item 3 do processo:
      var titulo = corpo.appendParagraph("3\tDados do Prescritor");
      titulo.setHeading(DocumentApp.ParagraphHeading.HEADING1).setFontSize(12).setFontFamily("Arial").setBold(true);  
      var texto = corpo.appendParagraph("3.1\tUF do CRM: " + uf_crm);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("3.2\tNúmero de registro no Conselho Regional de Medicina: " + numero_crm);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("3.3\tNome do Médico: " + nome_medico);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");

      // Adiciona item 4 do processo:
      var titulo = corpo.appendParagraph("4\tDados da Prescrição");
      titulo.setHeading(DocumentApp.ParagraphHeading.HEADING1).setFontSize(12).setFontFamily("Arial").setBold(true);  
      var texto = corpo.appendParagraph("4.1\tTipo: " + abaTecnologia.getRange(3, 2).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("4.2\tDenominação:  " + abaTecnologia.getRange(4, 2).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("4.3\tCID: " + cid_original);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("4.4\tPrescrição: " + prescricao);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);
      var texto = corpo.appendParagraph("4.5\tMeio(s) confirmatório(s) do diagnóstico disponibilizado(s): ");
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("4.6\tCapacidade funcional do paciente (ECOG Performance Status): " + ecog);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("4.7\tPaciente internado: " + internado);
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial"); 

      // IN THIS ITEM I WOULD LIKE TO ADD THE FOOTNOTE
      var text = "4.8\tUrgência";
      var texto = corpo.appendParagraph(text + " (conforme definição da Resolução CFM nº 1451/95: ocorrência imprevista de agravo à saúde com ou sem risco potencial de vida, cujo portador necessita de assistência médica imediata): " + urgencia);
texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");

      // Adiciona item 4.9
      var titulo = corpo.appendParagraph("4.9\tJustificativa para Prescrição").setFontSize(12).setFontFamily("Arial");
      titulo.setHeading(DocumentApp.ParagraphHeading.HEADING1).setFontSize(12).setFontFamily("Arial").setBold(true);
      var texto = corpo.appendParagraph("\nINSERIR HISTÓRIA CLÍNICA\n")
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph(abaTecnologia.getRange(8, 1).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      texto.setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY)

      // Adiciona item 5 do processo:
      var titulo = corpo.appendParagraph("5\tDados da Tecnologia");
      titulo.setHeading(DocumentApp.ParagraphHeading.HEADING1).setFontSize(12).setFontFamily("Arial").setBold(true);  
      var texto = corpo.appendParagraph("5.1\tRegistro na ANVISA: " + abaTecnologia.getRange(11, 2).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("5.2\tIndicação em conformidade com a aprovada no registro: " + abaTecnologia.getRange(12, 2).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("5.3\tExiste genérico ou similar: " + abaTecnologia.getRange(13, 2).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("5.4\tParecer da CONITEC: " + abaTecnologia.getRange(14, 2).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);
      var texto = corpo.appendParagraph("5.5\tDisponível no SUS: " + abaTecnologia.getRange(15, 2).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);
      var texto = corpo.appendParagraph("5.6\tPrevisto em Protocolo Clínico e Diretrizes Terapêuticas do Ministério da Saúde para a situação clínica do demandante: " + abaTecnologia.getRange(16, 2).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);
      var texto = corpo.appendParagraph("5.7\tAlternativa disponível no SUS: " + abaTecnologia.getRange(17, 2).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY); 
      var texto = corpo.appendParagraph("5.8\tNegativa administrativa: " + negativa_administrativa);
texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY); 

      // Adiciona itens 6 do processo
      var titulo = corpo.appendParagraph("6\tParecer do Consultor/Perito");
      titulo.setHeading(DocumentApp.ParagraphHeading.HEADING1).setFontSize(12).setFontFamily("Arial").setBold(true);
      var texto = corpo.appendParagraph("6.1\tEfetividade, eficácia e segurança: \n" + abaTecnologia.getRange(21, 1).getValue() + "\n");
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);
      var texto = corpo.appendParagraph("6.2\tBenefício/efeito/resultado esperado da tecnologia: " + abaTecnologia.getRange(22, 2).getValue() + "\n");
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);
      var texto = corpo.appendParagraph("6.3\tCusto: ");
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");

      // Adiciona informações antes da tabela
      var texto = corpo.appendParagraph("365 x nº vezes por dia / nº comprimidos na caixa. 52 semanas = (364 dias) / semanas do ciclo. Nº de ciclos no ano x qtdade inteira (com sobra/com o descarte) de medicação necessário por ciclo. Nºs sempre arredondados para cima. Obs.: checar se a estabilidade da reconstituição fármaco permite aproveitamento de sobras de um ciclo para o outro. Cálculo diverso nesse caso! Havendo possibilidade de reaproveitamento = 52 / nºs de ciclos x qtdade fracionada para dose correta.")
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(10).setFontFamily("Arial");

      corpo = adiciona_tabela(corpo, abaTecnologia);
      var texto = corpo.appendParagraph("* Valor unitário considerado a partir de consulta de preço da tabela CMED. Preço máximo de venda ao governo (PMVG) no Rio Grande do Sul (ICMS 17%). O PMVG é o resultado da aplicação do Coeficiente de Adequação de Preços (CAP) sobre o Preço Fábrica – PF, PMVG = PF*(1-CAP). O CAP, regulamentado pela Resolução nº. 3, de 2 de março de 2011, é um desconto mínimo obrigatório a ser aplicado sempre que forem realizadas vendas de medicamentos constantes do rol anexo ao Comunicado nº 15, de 31 de agosto de 2017 - Versão Consolidada ou para atender ordem judicial. Conforme o Comunicado CMED nº 5, de 21 de dezembro de 2020, o CAP é de 21,53%. Alguns medicamentos possuem isenção de ICMS para aquisição por órgãos da Administração Pública Direta Federal, Estadual e Municipal, conforme Convênio ICMS nº 87/02, sendo aplicado o benefício quando cabível.\n").setFontSize(8).setFontSize(9).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);
      // Coloca texto abaixo da tabela de custo
      var texto = corpo.appendParagraph(abaTecnologia.getRange(26, 1).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);

      // Adiciona item 6.4 a 6.6
      var texto = corpo.appendParagraph("6.4\tConclusão técnica: " + abaTecnologia.getRange(27, 2).getValue() + "\n");
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var titulo = corpo.appendParagraph("6.5\tJustificativa: ");
      titulo.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph(abaTecnologia.getRange(54, 1).getValue() + abaTecnologia.getRange(29, 1).getValue() + "\n");
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);

      // Adiciona item 6.6
      var titulo = corpo.appendParagraph("6.6\tReferências: ");
      titulo.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph(abaTecnologia.getRange(32, 1).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);

      // Adiciona item 7
      var titulo = corpo.appendParagraph("7\tEmissão");
      titulo.setHeading(DocumentApp.ParagraphHeading.HEADING1).setFontSize(12).setFontFamily("Arial").setBold(true);
      var texto = corpo.appendParagraph("7.1\tPrimeira emissão de nota técnica sobre tecnologia de saúde associada ao CID: " + abaTecnologia.getRange(35, 2).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);
      var texto = corpo.appendParagraph("7.2\tNecessidade de interação com a parte autora: " + abaTecnologia.getRange(61, 2).getValue());
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);
      var texto = corpo.appendParagraph("7.3\tProfissional da saúde responsável pela nota técnica: ");
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("7.4\tProfissional de saúde revisor: ");
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("7.5\tInstituição responsável: TelessaúdeRS-UFRGS");
      texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
      var texto = corpo.appendParagraph("7.6    Declaração de conflito de interesses: os autores da nota técnica declaram não possuir qualquer interesse na prescrição do tratamento postulado pela demanda e tampouco mantém vínculo, incluindo patrocínios diversos, com a indústria que o produz ou com o médico que assiste à parte autora.");
      
texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial").setAlignment(DocumentApp.HorizontalAlignment.JUSTIFY);

// Saving and closing as Tanaike suggested
document.saveAndClose();

// I guess this content variable is saving everything else in the document as well
var content = Docs.Documents.get(id).body.content.pop();

// Callling the function with the document id and the new content variable (as the new suggestion by @Tanaike)
createFootnoteWithText(id, content.startIndex + text.length);;

These are the functions to insert the footnote:

// This function was edited as suggested by @Tanaike
function createFootnoteWithText(id, bodyIndex) {
  text = 'Entendemos que o termo imediato é o definidor principal desse conceito. Nessas situações o paciente não pode esperar nem mesmo alguns poucos dias, sendo necessário seu encaminhamento imediato para uma emergência médica e, se houver indicação, proceder à internação hospitalar.';
  const createFootnoteReplies = createFootnote_(bodyIndex, id);
  if (createFootnoteReplies && createFootnoteReplies.replies.length) {
    const reply = createFootnoteReplies.replies[0];
    return appendTextTo_(text, reply.createFootnote.footnoteId, id);
  }
  return {issue: 'no replies', createFootnoteReplies };
}

function createFootnote_(bodyIndex, id) {
  return Docs.Documents.batchUpdate(
    {
      requests: {
        createFootnote: {
          location: {
            index: bodyIndex,
          },
        },
      },
    },
    id
  );
}

function appendTextTo_(text, segmentId = "", id) {
  return Docs.Documents.batchUpdate(
    {
      requests: {
        insertText: {
          text,
          endOfSegmentLocation: {
            segmentId,
          },
        },
      },
    },
    id
  );
}

After the new modifications suggested by @Tanaike the document appears like this (as you can see the footnote got inserted in the last page):

document as the output of the code

1 Answers1

1

In the case of your showing script, how about the following modification?

Modified script:

From your showing script, how about using saveAndClose() as follows? I thought that in your flow, in order to retrieve the appended paragraph by Document service (DocumentApp), it is required to save the document. By saving the document, the value of bodyIndex can be used for the middle of the paragraph.

function createFootnoteWithText(id, bodyIndex) {
  text = 'Entendemos que o termo imediato é o definidor principal desse conceito. Nessas situações o paciente não pode esperar nem mesmo alguns poucos dias, sendo necessário seu encaminhamento imediato para uma emergência médica e, se houver indicação, proceder à internação hospitalar.';
  const createFootnoteReplies = createFootnote_(bodyIndex, id);
  if (createFootnoteReplies && createFootnoteReplies.replies.length) {
    const reply = createFootnoteReplies.replies[0];
    return appendTextTo_(text, reply.createFootnote.footnoteId, id);
  }
  return { issue: 'no replies', createFootnoteReplies };
}

function createFootnote_(bodyIndex, id) {
  return Docs.Documents.batchUpdate(
    {
      requests: {
        createFootnote: {
          location: {
            index: bodyIndex,
          },
        },
      },
    },
    id
  );
}

function appendTextTo_(text, segmentId = "", id) {
  return Docs.Documents.batchUpdate(
    {
      requests: {
        insertText: {
          text,
          endOfSegmentLocation: {
            segmentId,
          },
        },
      },
    },
    id
  );
}

// Please run this script.
function main() {
  var doc = DocumentApp.getActiveDocument();
  var id = doc.getId();
  var corpo = doc.getBody();
  var urgencia = "sample";
  // Appending the text do the document body
  var text = "4.8\tUrgência";
  var texto = corpo.appendParagraph(text + " (conforme definição da Resolução CFM nº 1451/95: ocorrência imprevista de agravo à saúde com ou sem risco potencial de vida, cujo portador necessita de assistência médica imediata): " + urgencia);
  texto.setHeading(DocumentApp.ParagraphHeading.NORMAL).setFontSize(12).setFontFamily("Arial");
  doc.saveAndClose();
  var content = Docs.Documents.get(id).body.content.pop();

  // Callling the function with the document id
  createFootnoteWithText(id, content.startIndex + text.length);
}

Testing:

When this modified script is used, the following result is obtained.

enter image description here

Reference:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • ! Thank you so much for your help. I made the modifications that you suggested, but my document is very big (it has a front page and multiple tables) and when I run your code the footnote is being inserted in the front page (I will edit my question to show how the page is being saved). – Frederico Falcetta Jul 13 '22 at 10:42
  • @Frederico Falcetta Thank you for replying. I apologize for the inconvenience. About your reply, I thought that the reason of your issue is due to that your document has already had the texts. For this, I updated my proposed script. Could you pleasec confirm it? If that was not useful, I apologize again. – Tanaike Jul 13 '22 at 14:21
  • you are a life saver! I think I am getting there, but now the footnote is in the end of the document. I am going to edit my question with more of my code to make it clearer. – Frederico Falcetta Jul 13 '22 at 16:35
  • @Frederico Falcetta Thank you for replying. I have to apologize for my poor English skill. Unfortunately, I cannot understand your new issue from `After the new modifications suggested by @Tanaike the document appears like this (as you can see the footnote got inserted in the last page):`. Can I ask you about the detail of it? In your showing script, the text is put to the last of the document body. I followed your this direction. – Tanaike Jul 13 '22 at 23:26
  • Thank you for replying @Tanaike! I uploaded just a fraction of my code since the code is very big (400 lines approx.). The footnote has to be inserted in the middle of the document. I have lots of information before the footnote and then lots of information after the footnote. – Frederico Falcetta Jul 16 '22 at 18:14
  • @Frederico Falcetta Thank you for replying. I have to apologize for my poor English skill. Unfortunately, from `The footnote has to be inserted in the middle of the document. I have lots of information before the footnote and then lots of information after the footnote.`, I cannot imagine your situation. In order to correctly understand your situation, can you provide the simple sample input and output situation you expect? By this, I would like to try to understand your situation. If you can cooperate to resolve your issue, I'm glad. Can you cooperate to do it? – Tanaike Jul 16 '22 at 23:37
  • Thanks again for replying @Tanaike! Sorry for taking so long to respond. We had a newborn baby ad I didn't have the time to reply. I'm putting all the code from my function so that I can be clearer. – Frederico Falcetta Jul 24 '22 at 02:01
  • @Frederico Falcetta Thank you for replying. I have to apologize for my poor English skill. Unfortunately, I cannot understand the relationship between your updated script and my proposed script. Can I ask you about the detail of it? – Tanaike Jul 24 '22 at 02:07