Combinar datos en diapositivas

Una aplicación muy útil de la Slides API es la combinación de información de una o más fuentes de datos en un lote de diapositivas con plantilla.

Diagrama conceptual de combinación de correos

Existen varias razones por las cuales este enfoque resulta útil. Entre ellas se incluyen las siguientes:

  • Los diseñadores pueden optimizar el diseño de una presentación usando el editor Google Slides. Esto es mucho más sencillo que ajustar parámetros de tu app para retocar el diseño de las diapositivas representadas.

  • Un principio de diseño conocido que proporciona muchos beneficios es el de separar el contenido de la presentación.

En esta página, se describe la forma en que puedes tomar datos de una fuente externa e insertarlos en una presentación de “plantilla” existente. El concepto es similar al de una combinación de correos, y se emplean un procesador de texto y una hoja de cálculo.

Una receta básica

A continuación, se ofrece un ejemplo de la manera en que puedes combinar datos en una presentación con la Slides API. La secuencia completa de pasos es la siguiente:

  1. Crea tu presentación exactamente como deseas que aparezca usando contenido ficticio a modo de ayuda para el diseño.

  2. Para cada elemento de contenido que insertarás, reemplaza el contenido ficticio por una etiqueta. Las etiquetas son simplemente cuadros de texto con una string única.

  3. En tu código, usa la Google Drive API para realizar una copia nueva de la presentación.

  4. En tu código, usa el método batchUpdate de la Slides API con un conjunto de solicitudes replaceAllText, para realizar todas las sustituciones de texto en toda la presentación. Usa solicitudes replaceAllShapesWithImage para realizar sustituciones de imágenes en toda la presentación.

Al configurar etiquetas, asegúrate de usar strings que normalmente no aparecerían. Por ejemplo, {{account-holder-name}} podría funcionar bien como etiqueta.

Una vez que hayas creado un lote que contenga etiquetas, asegúrate de realizar una copia y usar la Slides API para manipular la copia. ¡No uses la Slides API para manipular la copia de tu copia patrón de “plantilla”!

En las siguientes secciones se incluyen fragmentos de código que muestran parte de este proceso.

Combinación de texto

Puedes usar una solicitud replaceAllText para reemplazar todas las instancias de una string de texto de una presentación por texto nuevo. Para realizar combinaciones, esto generalmente es mucho más sencillo que buscar y reemplazar cada instancia de texto de manera individual. Una razón por la cual este es el mejor enfoque es la dificultad para predecir los ID de los elementos de página, en especial cuando los trabajadores trabajan para definir mejor y mantener la presentación de la plantilla.

Ejemplo

En el siguiente ejemplo, se usa la Google Drive API para copiar una presentación de plantilla, con lo cual se crea una nueva instancia de la presentación. Luego se usa la Sheets API para leer datos de una hoja de cálculo de Google Sheets y, por último, se usa la Slides API para actualizar la nueva presentación.

En el ejemplo, se toman datos de tres celdas de una fila de un rango con nombre de la hoja de cálculo. Luego se sustituyen esos datos en la presentación donde tienen lugar las strings {{customer-name}}, {{case-description}} y {{total-portfolio}}.

Java

// Use the Sheets API to load data, one record per row.
String dataRangeNotation = "Customers!A2:M6";
ValueRange sheetsResponse = sheetsService.spreadsheets().values()
        .get(dataSpreadsheetId, dataRangeNotation).execute();
List<List<Object>> values = sheetsResponse.getValues();

// For each record, create a new merged presentation.
for (List<Object> row: values) {
    String customerName = row.get(2).toString();     // name in column 3
    String caseDescription = row.get(5).toString();  // case description in column 6
    String totalPortfolio = row.get(11).toString();  // total portfolio in column 12

    // Duplicate the template presentation using the Drive API.
    String copyTitle = customerName + " presentation";
    File content = new File().setName(copyTitle);
    File presentationFile =
            driveService.files().copy(templatePresentationId, content).execute();
    String presentationId = presentationFile.getId();

    // Create the text merge (replaceAllText) requests for this presentation.
    List<Request> requests = new ArrayList<>();
    requests.add(new Request()
            .setReplaceAllText(new ReplaceAllTextRequest()
                    .setContainsText(new SubstringMatchCriteria()
                            .setText("{{customer-name}}")
                            .setMatchCase(true))
                    .setReplaceText(customerName)));
    requests.add(new Request()
            .setReplaceAllText(new ReplaceAllTextRequest()
                    .setContainsText(new SubstringMatchCriteria()
                            .setText("{{case-description}}")
                            .setMatchCase(true))
                    .setReplaceText(caseDescription)));
    requests.add(new Request()
            .setReplaceAllText(new ReplaceAllTextRequest()
                    .setContainsText(new SubstringMatchCriteria()
                            .setText("{{total-portfolio}}")
                            .setMatchCase(true))
                    .setReplaceText(totalPortfolio)));

    // Execute the requests for this presentation.
    BatchUpdatePresentationRequest body =
            new BatchUpdatePresentationRequest().setRequests(requests);
    BatchUpdatePresentationResponse response =
            slidesService.presentations().batchUpdate(presentationId, body).execute();

Python

# Use the Sheets API to load data, one record per row.
data_range_notation = 'Customers!A2:M6'
sheets_response = sheets_service.spreadsheets().values().get(
    spreadsheetId=data_spreadsheet_id, range=data_range_notation).execute()
values = sheets_response.get('values')

# For each record, create a new merged presentation.
for row in values:
    customer_name = row[2]       # name in column 3
    case_description = row[5]    # case description in column 6
    total_portfolio = row[11]    # total portfolio in column 12

    # Duplicate the template presentation using the Drive API.
    copy_title = customer_name + ' presentation'
    body = {
        'name': copy_title
    }
    drive_response = drive_service.files().copy(
        fileId=template_presentation_id, body=body).execute()
    presentation_copy_id = drive_response.get('id')

    # Create the text merge (replaceAllText) requests for this presentation.
    requests = [
        {
            'replaceAllText': {
                'containsText': {
                    'text': '{{customer-name}}',
                    'matchCase': True
                },
                'replaceText': customer_name
            }
        },
        {
            'replaceAllText': {
                'containsText': {
                    'text': '{{case-description}}',
                    'matchCase': True
                },
                'replaceText': case_description
            }
        },
        {
            'replaceAllText': {
                'containsText': {
                    'text': '{{total-portfolio}}',
                    'matchCase': True
                },
                'replaceText': total_portfolio
            }
        }
    ]

    # Execute the requests for this presentation.
    body = {
        'requests': requests
    }
    response = slides_service.presentations().batchUpdate(
        presentationId=presentation_copy_id, body=body).execute()

PHP

// Use the Sheets API to load data, one record per row.
$dataRangeNotation = 'Customers!A2:M6';
$sheetsResponse =
  $sheetsService->spreadsheets_values->get($dataSpreadsheetId, $dataRangeNotation);
$values = $sheetsResponse['values'];

// For each record, create a new merged presentation.
foreach($values as $row) {
  $customerName = $row[2];     // name in column 3
  $caseDescription = $row[5];  // case description in column 6
  $totalPortfolio = $row[11];  // total portfolio in column 12

  // Duplicate the template presentation using the Drive API.
  $copy = new Google_Service_Drive_DriveFile(array(
    'name' => $customerName . ' presentation'
  ));
  $driveResponse = $driveService->files->copy($templatePresentationId, $copy);
  $presentationCopyId = $driveResponse->id;

  // Create the text merge (replaceAllText) requests for this presentation.
  $requests = array();
  $requests[] = new Google_Service_Slides_Request(array(
    'replaceAllText' => array(
      'containsText' => array(
        'text' => '{{customer-name}}',
        'matchCase' => true
      ),
      'replaceText' => $customerName
    )
  ));
  $requests[] = new Google_Service_Slides_Request(array(
    'replaceAllText' => array(
      'containsText' => array(
        'text' => '{{case-description}}',
        'matchCase' => true
      ),
      'replaceText' => $caseDescription
    )
  ));
  $requests[] = new Google_Service_Slides_Request(array(
    'replaceAllText' => array(
      'containsText' => array(
        'text' => '{{total-portfolio}}',
        'matchCase' => true
      ),
      'replaceText' => $totalPortfolio
    )
  ));

  // Execute the requests for this presentation.
  $batchUpdateRequest = new Google_Service_Slides_BatchUpdatePresentationRequest(array(
    'requests' => $requests
  ));
  $response =
    $slidesService->presentations->batchUpdate($presentationCopyId, $batchUpdateRequest);

Combinación de imágenes

También puedes combinar imágenes en tu presentación usando una solicitud replaceAllShapesWithImage. Con esta solicitud se reemplazan por la imagen provista todas las instancias de formas que contengan la string de texto proporcionada. Con esta solicitud, de manera automática se posiciona la imagen y se ajusta su escala para que encaje dentro de los límites de la forma de la etiqueta y, al mismo tiempo, se preserve su relación de aspecto.

Ejemplo

En el siguiente ejemplo, se usa la Google Drive API para copiar una presentación de plantilla, con lo cual se crea una nueva instancia de la presentación. Luego se usa la Slides API para hallar las formas que contengan el texto {{company-logo}} y reemplazarlo por la imagen del logotipo de una empresa. La solicitud también reemplazará cualquier forma que contenga el texto {{customer-graphic}} por una imagen diferente.

Java

// Duplicate the template presentation using the Drive API.
String copyTitle = customerName + " presentation";
File content = new File().setName(copyTitle);
File presentationFile =
        driveService.files().copy(templatePresentationId, content).execute();
String presentationId = presentationFile.getId();

// Create the image merge (replaceAllShapesWithImage) requests.
List<Request> requests = new ArrayList<>();
requests.add(new Request()
        .setReplaceAllShapesWithImage(new ReplaceAllShapesWithImageRequest()
                .setImageUrl(logoUrl)
                .setReplaceMethod("CENTER_INSIDE")
                .setContainsText(new SubstringMatchCriteria()
                        .setText("{{company-logo}}")
                        .setMatchCase(true))));
requests.add(new Request()
        .setReplaceAllShapesWithImage(new ReplaceAllShapesWithImageRequest()
                .setImageUrl(customerGraphicUrl)
                .setReplaceMethod("CENTER_INSIDE")
                .setContainsText(new SubstringMatchCriteria()
                        .setText("{{customer-graphic}}")
                        .setMatchCase(true))));

// Execute the requests.
BatchUpdatePresentationRequest body =
        new BatchUpdatePresentationRequest().setRequests(requests);
BatchUpdatePresentationResponse response =
        slidesService.presentations().batchUpdate(presentationId, body).execute();

// Count total number of replacements made.
int numReplacements = 0;
for(Response resp: response.getReplies()) {
    numReplacements += resp.getReplaceAllShapesWithImage().getOccurrencesChanged();
}

System.out.println("Created merged presentation with ID: " + presentationId);
System.out.println("Replaced " + numReplacements + " shapes instances with images.");

Python

# Duplicate the template presentation using the Drive API.
copy_title = customer_name + ' presentation'
drive_response = drive_service.files().copy(
    fileId=template_presentation_id, body={'name': copy_title}).execute()
presentation_copy_id = drive_response.get('id')

# Create the image merge (replaceAllShapesWithImage) requests.
requests = []
requests.append({
    'replaceAllShapesWithImage': {
        'imageUrl': logo_url,
        'replaceMethod': 'CENTER_INSIDE',
        'containsText': {
            'text': '{{company-logo}}',
            'matchCase': True
        }
    }
})
requests.append({
    'replaceAllShapesWithImage': {
        'imageUrl': customer_graphic_url,
        'replaceMethod': 'CENTER_INSIDE',
        'containsText': {
            'text': '{{customer-graphic}}',
            'matchCase': True
        }
    }
})

# Execute the requests.
body = {
    'requests': requests
}
response = slides_service.presentations().batchUpdate(
    presentationId=presentation_copy_id, body=body).execute()

# Count the number of replacements made.
num_replacements = 0
for reply in response.get('replies'):
    num_replacements += reply.get('replaceAllShapesWithImage').get('occurrencesChanged')
print('Created merged presentation with ID: {0}'.format(presentation_copy_id))
print('Replaced %d shapes with images.' % num_replacements)

PHP

// Duplicate the template presentation using the Drive API.
$copy = new Google_Service_Drive_DriveFile(array(
  'name' => $customerName . ' presentation'
));
$driveResponse = $driveService->files->copy($templatePresentationId, $copy);
$presentationCopyId = $driveResponse->id;

// Create the image merge (replaceAllShapesWithImage) requests.
$requests = array();
$requests[] = new Google_Service_Slides_Request(array(
  'replaceAllShapesWithImage' => array(
    'imageUrl' => $logoUrl,
    'replaceMethod' => 'CENTER_INSIDE',
    'containsText' => array(
      'text' => '{{company-logo}}',
      'matchCase' => true
    )
  )
));
$requests[] = new Google_Service_Slides_Request(array(
  'replaceAllShapesWithImage' => array(
    'imageUrl' => $customerGraphicUrl,
    'replaceMethod' => 'CENTER_INSIDE',
    'containsText' => array(
      'text' => '{{customer-graphic}}',
      'matchCase' => true
    )
  )
));

// Execute the requests.
$batchUpdateRequest = new Google_Service_Slides_BatchUpdatePresentationRequest(array(
  'requests' => $requests
));
$response =
  $slidesService->presentations->batchUpdate($presentationCopyId, $batchUpdateRequest);

// Count the total number of replacements made.
$numReplacements = 0;
foreach($response->getReplies() as $reply) {
  $numReplacements += $reply->getReplaceAllShapesWithImage()->getOccurrencesChanged();
}
printf("Created presentation for %s with ID: %s\n", $customerName, $presentationCopyId);
printf("Replaced %d shapes with images.\n", $numReplacements);

Reemplazo de instancias específicas de cuadros de texto o imágenes

Las solicitudes replaceAllText y replaceAllShapesWithImage resultan útiles para reemplazar etiquetas en toda una presentación, pero a veces solo es necesario reemplazar elementos conforme a determinados criterios, como la ubicación en una diapositiva específica.

En estos casos, debes obtener los ID de las formas de etiquetas que desees reemplazar. Para el reemplazo de texto, debes borrar el que se encuentre en esas formas y luego insertar el texto nuevo (consulta el ejemplo Editar texto de una forma especificada).

El reemplazo de imágenes es más complejo. Para la combinación de una imagen, debes:

  1. Obtener el ID de la forma de etiqueta.
  2. Copiar la información sobre tamaño y transformación de la etiqueta.
  3. Agregar tu imagen a la página usando la información sobre tamaño y transformación.
  4. Borrar la forma de etiqueta.

Para preservar la relación de aspecto de la imagen y, al mismo tiempo, ajustarla al tamaño deseado es posible que se deba proceder con cuidado, como se indica en los párrafos siguientes. Consulta también el ejemplo de Reemplazar una etiqueta de forma por una imagen.

Preservar la relación de aspecto

Cuando se crean imágenes usando la Slides API, la adecuación de aspecto se basa únicamente en el tamaño de la imagen; no depende de los datos de tamaño y transformación. Los datos sobre tamaño que proporciones en la solicitud createImage se consideran como el tamaño de imagen deseado. La API adecua la relación de aspecto de la imagen a este tamaño deseado y luego aplica la transformación proporcionada.

Cuando se reemplaza una etiqueta por una imagen, se preserva la relación de aspecto de la imagen configurando el tamaño y el ajuste de escala de esta de la siguiente manera:

  • width: se debe configurar conforme a los parámetros width y scaleX del producto de la etiqueta.
  • height: se debe configurar conforme a los parámetros height y scaleY del producto de la etiqueta.
  • scale_x: se debe configurar conforme al parámetro 1.
  • scale_y: se debe configurar conforme al parámetro 1.

Esto hace que la Slides API adecue el aspecto de la imagen conforme al tamaño de visualización de la etiqueta, en lugar del tamaño sin ajuste de escala (consulta Reemplazar una etiqueta de forma por una imagen). Fijando los parámetros de ajuste de escala en 1 se puede evitar que este ajuste se aplique dos veces a la imagen.

Esta disposición garantiza la preservación de la relación de aspecto y evita que la imagen supere el tamaño de la forma de etiqueta. La imagen tendrá el mismo punto central que la forma de etiqueta.

Manejo de plantillas

Para presentaciones de plantillas definidas por la aplicación y atribuidas a ella, crea la plantilla usando una cuenta dedicada que represente la aplicación. Las cuentas de servicio son una buena opción y evitan complicaciones con políticas de GSuite que restrinjan el uso compartido.

Cuando crees instancias de presentaciones a partir de plantillas, usa siempre credenciales de usuario final. Esto permite a los usuarios controlar por completo la presentación resultante y evita problemas de ajuste de escala relacionados con límites por usuario en Google Drive.

Para crear una plantilla usando una cuenta de servicio, aplica los siguientes pasos usando las credenciales de la aplicación:

  1. Crea una nueva presentación usando presentation.create, de la Slides API
  2. Actualiza los permisos a fin de autorizar la lectura por parte de cualquier persona usando files.permissions.insert, de la Drive API
  3. Actualiza los permisos para permitir la lectura por parte de los autores de plantillas usando files.permissions.insert, de la Drive API
  4. Edita la plantilla según sea necesario.

Para crear una nueva instancia de la presentación, aplica los siguientes pasos usando las credenciales de usuario:

  1. Crea una copia de la plantilla usando files.copy, de la Drive API
  2. Reemplaza los valores usando presentation.batchUpdate, de la Slides API.

Enviar comentarios sobre…

¿Necesitas ayuda? Visita nuestra página de asistencia.