טבלאות צירים

במדריך הזה מוסבר איך משתמשים ב-Google Sheets API כדי ליצור טבלאות צירים בגיליונות אלקטרוניים, ומוסבר למה כדאי לעשות זאת.

מהי טבלת צירים?

טבלאות צירים מאפשרות לסכם נתונים בגיליון האלקטרוני, על ידי צבירת הנתונים, מיון, ספירה או חישוב הממוצע שלהם באופן אוטומטי, תוך הצגת התוצאות הסיכומיות בטבלה חדשה. טבלת צירים פועלת כסוג של שאילתה מול קבוצת נתוני מקור. נתוני המקור האלה נמצאים במקום אחר בגיליון האלקטרוני, וטבלת הצירים מציגה תצוגה מעובדת של הנתונים.

לדוגמה, נניח את קבוצת נתוני המכירות הבאה:

A B C D E F G
1 קטגוריית פריט מספר הדגם עלות כמות אזור אנשי מכירות תאריך משלוח
2 גלגל ענק W-24 20.50$‎ 4 מערב Beth 1.3.2016
3 דלת D-01X ‎$15.00 2 דרום Amir 15/03/2016
4 מנוע ENG-0134 $100.00 1 צפון Carmen 20/03/2016
5 מסגרת FR-0B1 34.00$ 8 מזרח חנה 3/12/2016
6 חלונית P-034 24.00 ש"ח 4 צפון דניאל 2/04/2016
7 חלונית P-052 11.50$‎ 7 מזרח אריק 16/05/2016
8 גלגל ענק W-24 20.50$‎ 11 דרום Sheldon 30/04/2016
9 מנוע ENG-0161 330.00$‎ 2 צפון ג'סי 2/7/2016
10 דלת D-01Y 29.00 6 מערב Armando 13/03/2016
11 מסגרת FR-0B1 34.00$ 9 דרום Yuliana 27/02/2016
12 חלונית P-102 12 ש"ח 15 מערב Carmen 18/04/2016
13 חלונית P-105 8.25$‎ 13 מערב ג'סי 20/06/2016
14 מנוע ENG-0211 283.00$‎ 1 צפון Amir 21/06/2016
15 דלת D-01X ‎$15.00 2 מערב Armando 3.7.2016
16 מסגרת FR-0B1 34.00$ 6 דרום Carmen 15/07/2016
17 גלגל ענק W-25 80 ש"ח 8 דרום חנה 2/05/2016
18 גלגל ענק W-11 29.00 13 מזרח אריק 19/05/2016
19 דלת D-05 17.70$ 7 מערב Beth 28/06/2016
20 מסגרת FR-0B1 34.00$ 8 צפון Sheldon 30/03/2016

אפשר להשתמש בטבלת צירים כדי ליצור דוח שבו מוצג כמה מכשירי כל מספר מודל נמכרו בכל אזור:

צילום מסך של טבלת צירים שמציגה את מספרי הדגמים לפי אזור

קוד המקור ששימש ליצירת טבלת הצירים הזו מופיע בקטע דוגמה שבהמשך.

אחרי שמוסיפים טבלת צירים לגיליון אלקטרוני, המשתמשים יכולים לשנות באופן אינטראקטיבי את המבנה והפרטים של הסיכום באמצעות ממשק המשתמש של Sheets.

עבודה עם טבלאות צירים

ההגדרה של טבלת צירים משויכת לתא יחיד בגיליון. למרות שהתצוגה הנגזרת שלה כוללת הרבה תאים גם בגובה וגם ברוחב, מבחינה פרוגרמטית היא ממוקמת בקואורדינטה של תא אחד. התא הזה הופך לפינה הימנית העליונה של טבלת הצירים שעברתה רינדור, והיקף האופק והאנכה שלו נקבע לפי ההגדרה שלו.

הוספת טבלת צירים

כדי להוסיף טבלת צירים, משתמשים בשיטה batchUpdate ומספקים בקשה מסוג updateCells. משתמשים בבקשה הזו כדי לספק הגדרה של PivotTable כתוכן של תא, כפי שמוצג בהמשך:

"updateCells": {
  "rows": {
    "values": [{
      "pivotTable": MyPivotTable
    },
    "start": {
      "sheetId": sheetId,
      "rowIndex": 0,
      "columnIndex": 0
    },
    "fields": "pivotTable"
  }

הפונקציה הזו ממוקמת את טבלת הצירים שמתוארת על ידי MyPivotTable בגיליון שצוין, עם הפינה הימנית העליונה בתא A1. (הגובה והרוחב של טבלת הצירים הם דינמיים, מציינים רק את המקור).

הסוג PivotTable מאפשר לכם לציין:

  • טווח נתוני המקור
  • שדה אחד או יותר שהנתונים שלו ירכיבו את השורות של טבלת הצירים
  • שדה אחד או יותר שהנתונים שלו ירכיבו את העמודות של טבלת הצירים
  • קריטריונים לסינון ולצבירה
  • פריסה של טבלת צירים

שינוי ומחיקה של טבלאות צירים

אין בקשות מפורשות לשינוי או למחיקה של טבלת צירים. במקום זאת, צריך להשתמש בבקשה updateCells עם תוכן תא שונה:

  • כדי לשנות טבלת צירים, יוצרים הגדרה של PivotTable ששונתה ומעדכנים את התא באמצעותה, בדומה להוספת טבלת צירים חדשה.
  • כדי למחוק טבלת צירים, מעדכנים את התא בערכים ריקים. לדוגמה, תוכלו לעיין בדוגמה מחיקת טבלת צירים.

תרחישים לדוגמה

יש שימושים רבים לשולחנות צירים, במגוון רחב של תחומים, כולל ניתוח סטטיסטי, אפליקציות ERP, דיווח פיננסי ועוד. תרחישים לדוגמה לשימוש בטבלאות צירים קלאסיות כוללים פריטים כמו:

  • סה"כ מכירות לפי אזור ורבעון
  • משכורת ממוצעת לפי תפקיד ומיקום
  • מספר התקריות לפי מוצר ושעה ביום

יש מספר עצום של יישומים פוטנציאליים לטבלאות צירים, והיכולת ליצור אותן באופן פרוגרמטי היא כלי חזק. אפשר ליצור טבלאות צירים שתומכות בניתוחים אינטראקטיביים, אבל מותאמות לנסיבות ספציפיות. לדוגמה:

  • ניתוח נתוני אירועים מהתקופה של 24 השעות האחרונות
  • הצגה או ניתוח של נתונים מצטברים שתואמים לחשבון שנבחר כרגע
  • בדיקת נתוני המכירות בטריטוריות ששייכות למשתמש הנוכחי

דוגמה

בדוגמה הזו נוצרת טבלת צירים מקבוצת נתונים כדי ליצור את הדוח 'מספר דגם לפי אזור' שמוצג בתחילת הדף. דוגמאות נוספות מפורטות בדף טבלת צירים לדוגמה.

Apps Script

sheets/api/spreadsheet_snippets.gs
/**
 * Create pivot table
 * @param {string} spreadsheetId spreadsheet ID
 * @returns {*} pivot table's spreadsheet
 */
Snippets.prototype.pivotTable = (spreadsheetId) => {
  try {
    const spreadsheet = SpreadsheetApp.openById(spreadsheetId);

    // Create two sheets for our pivot table, assume we have one.
    let sheet = spreadsheet.getSheets()[0];
    sheet.copyTo(spreadsheet);

    const sourceSheetId = spreadsheet.getSheets()[0].getSheetId();
    const targetSheetId = spreadsheet.getSheets()[1].getSheetId();

    // Create pivot table
    const pivotTable = Sheets.newPivotTable();

    let gridRange = Sheets.newGridRange();
    gridRange.sheetId = sourceSheetId;
    gridRange.startRowIndex = 0;
    gridRange.startColumnIndex = 0;
    gridRange.endRowIndex = 20;
    gridRange.endColumnIndex = 7;
    pivotTable.source = gridRange;

    let pivotRows = Sheets.newPivotGroup();
    pivotRows.sourceColumnOffset = 1;
    pivotRows.showTotals = true;
    pivotRows.sortOrder = 'ASCENDING';
    pivotTable.rows = pivotRows;

    let pivotColumns = Sheets.newPivotGroup();
    pivotColumns.sourceColumnOffset = 4;
    pivotColumns.sortOrder = 'ASCENDING';
    pivotColumns.showTotals = true;
    pivotTable.columns = pivotColumns;

    let pivotValue = Sheets.newPivotValue();
    pivotValue.summarizeFunction = 'COUNTA';
    pivotValue.sourceColumnOffset = 4;
    pivotTable.values = [pivotValue];

    // Create other metadata for the updateCellsRequest
    let cellData = Sheets.newCellData();
    cellData.pivotTable = pivotTable;

    let rows = Sheets.newRowData();
    rows.values = cellData;

    let start = Sheets.newGridCoordinate();
    start.sheetId = targetSheetId;
    start.rowIndex = 0;
    start.columnIndex = 0;

    let updateCellsRequest = Sheets.newUpdateCellsRequest();
    updateCellsRequest.rows = rows;
    updateCellsRequest.start = start;
    updateCellsRequest.fields = 'pivotTable';

    // Batch update our spreadsheet
    let batchUpdate = Sheets.newBatchUpdateSpreadsheetRequest();
    let updateCellsRawRequest = Sheets.newRequest();
    updateCellsRawRequest.updateCells = updateCellsRequest;
    batchUpdate.requests = [updateCellsRawRequest];
    const response = Sheets.Spreadsheets.batchUpdate(batchUpdate,
      spreadsheetId);

    return response;
  } catch (err) {
    // TODO (developer) - Handle exception
    console.log('Failed with error %s', err.message);
  }
};

Java

sheets/snippets/src/main/java/PivotTables.java
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.sheets.v4.Sheets;
import com.google.api.services.sheets.v4.SheetsScopes;
import com.google.api.services.sheets.v4.model.AddSheetRequest;
import com.google.api.services.sheets.v4.model.BatchUpdateSpreadsheetRequest;
import com.google.api.services.sheets.v4.model.BatchUpdateSpreadsheetResponse;
import com.google.api.services.sheets.v4.model.CellData;
import com.google.api.services.sheets.v4.model.GridCoordinate;
import com.google.api.services.sheets.v4.model.GridRange;
import com.google.api.services.sheets.v4.model.PivotGroup;
import com.google.api.services.sheets.v4.model.PivotTable;
import com.google.api.services.sheets.v4.model.PivotValue;
import com.google.api.services.sheets.v4.model.Request;
import com.google.api.services.sheets.v4.model.RowData;
import com.google.api.services.sheets.v4.model.UpdateCellsRequest;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.collect.Lists;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/* Class to demonstrate the use of Spreadsheet Create Pivot Tables API */
public class PivotTables {
  /**
   * Create pivot table.
   *
   * @param spreadsheetId - Id of the spreadsheet.
   * @return pivot table's spreadsheet
   * @throws IOException - if credentials file not found.
   */
  public static BatchUpdateSpreadsheetResponse pivotTables(String spreadsheetId)
      throws IOException {
        /* Load pre-authorized user credentials from the environment.
           TODO(developer) - See https://developers.google.com/identity for
            guides on implementing OAuth2 for your application. */
    GoogleCredentials credentials = GoogleCredentials.getApplicationDefault()
        .createScoped(Collections.singleton(SheetsScopes.SPREADSHEETS));
    HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(
        credentials);

    // Create the sheets API client
    Sheets service = new Sheets.Builder(new NetHttpTransport(),
        GsonFactory.getDefaultInstance(),
        requestInitializer)
        .setApplicationName("Sheets samples")
        .build();

    // Create two sheets for our pivot table.
    List<Request> sheetsRequests = new ArrayList<>();
    BatchUpdateSpreadsheetResponse result = null;
    try {
      sheetsRequests.add(new Request().setAddSheet(new AddSheetRequest()));
      sheetsRequests.add(new Request().setAddSheet(new AddSheetRequest()));

      BatchUpdateSpreadsheetRequest createSheetsBody = new BatchUpdateSpreadsheetRequest()
          .setRequests(sheetsRequests);
      BatchUpdateSpreadsheetResponse createSheetsResponse = service.spreadsheets()
          .batchUpdate(spreadsheetId, createSheetsBody).execute();
      int sourceSheetId = createSheetsResponse.getReplies().get(0).getAddSheet().getProperties()
          .getSheetId();
      int targetSheetId = createSheetsResponse.getReplies().get(1).getAddSheet().getProperties()
          .getSheetId();

      PivotTable pivotTable = new PivotTable()
          .setSource(
              new GridRange()
                  .setSheetId(sourceSheetId)
                  .setStartRowIndex(0)
                  .setStartColumnIndex(0)
                  .setEndRowIndex(20)
                  .setEndColumnIndex(7)
          )
          .setRows(Collections.singletonList(
              new PivotGroup()
                  .setSourceColumnOffset(1)
                  .setShowTotals(true)
                  .setSortOrder("ASCENDING")
          ))
          .setColumns(Collections.singletonList(
              new PivotGroup()
                  .setSourceColumnOffset(4)
                  .setShowTotals(true)
                  .setSortOrder("ASCENDING")
          ))
          .setValues(Collections.singletonList(
              new PivotValue()
                  .setSummarizeFunction("COUNTA")
                  .setSourceColumnOffset(4)
          ));
      List<Request> requests = Lists.newArrayList();
      Request updateCellsRequest = new Request().setUpdateCells(new UpdateCellsRequest()
          .setFields("*")
          .setRows(Collections.singletonList(
              new RowData().setValues(
                  Collections.singletonList(
                      new CellData().setPivotTable(pivotTable))
              )
          ))
          .setStart(new GridCoordinate()
              .setSheetId(targetSheetId)
              .setRowIndex(0)
              .setColumnIndex(0)

          ));

      requests.add(updateCellsRequest);
      BatchUpdateSpreadsheetRequest updateCellsBody = new BatchUpdateSpreadsheetRequest()
          .setRequests(requests);
      result = service.spreadsheets().batchUpdate(spreadsheetId, updateCellsBody).execute();
    } catch (GoogleJsonResponseException e) {
      // TODO(developer) - handle error appropriately
      GoogleJsonError error = e.getDetails();
      if (error.getCode() == 404) {
        System.out.printf("Spreadsheet not found with id '%s'.\n", spreadsheetId);
      } else {
        throw e;
      }
    }
    return result;
  }
}

JavaScript

sheets/snippets/sheets_pivot_tables.js
function pivotTable(spreadsheetId, callback) {
  // Create two sheets for our pivot table
  const requests = [{
    addSheet: {},
  }, {
    addSheet: {},
  }];
  const batchUpdateRequest = {requests: requests};
  try {
    gapi.client.sheets.spreadsheets.batchUpdate({
      spreadsheetId: spreadsheetId,
      resource: batchUpdateRequest,
    }).then((response) => {
      const sourceSheetId = response.result.replies[0].addSheet.properties.sheetId;
      const targetSheetId = response.result.replies[1].addSheet.properties.sheetId;

      const requests = [{
        updateCells: {
          rows: {
            values: [{
              pivotTable: {
                source: {
                  sheetId: sourceSheetId,
                  startRowIndex: 0,
                  startColumnIndex: 0,
                  endRowIndex: 20,
                  endColumnIndex: 7,
                },
                rows: [{
                  sourceColumnOffset: 1,
                  showTotals: true,
                  sortOrder: 'ASCENDING',
                }],
                columns: [{
                  sourceColumnOffset: 4,
                  sortOrder: 'ASCENDING',
                  showTotals: true,
                }],
                values: [{
                  summarizeFunction: 'COUNTA',
                  sourceColumnOffset: 4,
                }],
                valueLayout: 'HORIZONTAL',
              },
            },
            ],
          },
          start: {
            sheetId: targetSheetId,
            rowIndex: 0,
            columnIndex: 0,
          },
          fields: 'pivotTable',
        },
      }];

      const body = {
        requests,
      };
      gapi.client.sheets.spreadsheets.batchUpdate({
        spreadsheetId: spreadsheetId,
        resource: body,
      }).then((response) => {
        if (callback) callback(response);
      });
    });
  } catch (err) {
    document.getElementById('content').innerText = err.message;
    return;
  }
}

Node.js

sheets/snippets/sheets_pivot_table.js
/**
 * Adds a pivot table to a spreadsheet.
 * @param {string} spreadsheetId The Spreadsheet to add the pivot table to.
 * @return {obj} spreadsheet information
 */
async function pivotTable(spreadsheetId) {
  const {GoogleAuth} = require('google-auth-library');
  const {google} = require('googleapis');

  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/spreadsheets',
  });

  const service = google.sheets({version: 'v4', auth});
  try {
    // Create two sheets for our pivot table
    let requests = [
      {
        addSheet: {},
      },
      {
        addSheet: {},
      },
    ];
    let resource = {requests};
    let response = await service.spreadsheets.batchUpdate({
      spreadsheetId,
      resource,
    });
    const sourceSheetId = response.data.replies[0].addSheet.properties.sheetId;
    const targetSheetId = response.data.replies[1].addSheet.properties.sheetId;

    requests = [
      {
        updateCells: {
          rows: {
            values: [
              {
                pivotTable: {
                  source: {
                    sheetId: sourceSheetId,
                    startRowIndex: 0,
                    startColumnIndex: 0,
                    endRowIndex: 20,
                    endColumnIndex: 7,
                  },
                  rows: [
                    {
                      sourceColumnOffset: 1,
                      showTotals: true,
                      sortOrder: 'ASCENDING',
                    },
                  ],
                  columns: [
                    {
                      sourceColumnOffset: 4,
                      sortOrder: 'ASCENDING',
                      showTotals: true,
                    },
                  ],
                  values: [
                    {
                      summarizeFunction: 'COUNTA',
                      sourceColumnOffset: 4,
                    },
                  ],
                  valueLayout: 'HORIZONTAL',
                },
              },
            ],
          },
          start: {
            sheetId: targetSheetId,
            rowIndex: 0,
            columnIndex: 0,
          },
          fields: 'pivotTable',
        },
      },
    ];
    resource = {
      requests,
    };
    response = service.spreadsheets.batchUpdate({
      spreadsheetId,
      resource,
    });
    return response;
  } catch (err) {
    // TODO (developer) - Handle exception
    throw err;
  }
}

PHP

sheets/snippets/src/SpreadsheetPivotTables.php
use Google\Client;
use Google\Service\Drive;
use Google\Service\Sheets\BatchUpdateSpreadsheetRequest;


function pivotTables($spreadsheetId)
    {
        /* Load pre-authorized user credentials from the environment.
           TODO(developer) - See https://developers.google.com/identity for
            guides on implementing OAuth2 for your application. */
        $client = new Google\Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope(Google\Service\Drive::DRIVE);
        $service = new Google_Service_Sheets($client);
        try{
            $requests = [
                new Google_Service_Sheets_Request([
                    'addSheet' => [
                        'properties' => [
                            'title' => 'Sheet 1'
                            ]
                ]
            ]),
            new Google_Service_Sheets_Request([
                'addSheet' => [
                    'properties' => [
                        'title' => 'Sheet 2'
                        ]
                        ]
                        ])
                    ];
                    // Create two sheets for our pivot table
                    $batchUpdateRequest = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest([
                        'requests' => $requests
                    ]);
        $batchUpdateResponse = $service->spreadsheets->batchUpdate($spreadsheetId, $batchUpdateRequest);
        $sourceSheetId = $batchUpdateResponse->replies[0]->addSheet->properties->sheetId;
        $targetSheetId = $batchUpdateResponse->replies[1]->addSheet->properties->sheetId;
        $requests = [
            'updateCells' => [
                'rows' => [
                    'values' => [
                        [
                            'pivotTable' => [
                                'source' => [
                                    'sheetId' => $sourceSheetId,
                                    'startRowIndex' => 0,
                                    'startColumnIndex' => 0,
                                    'endRowIndex' => 20,
                                    'endColumnIndex' => 7
                                ],
                                'rows' => [
                                    [
                                        'sourceColumnOffset' => 1,
                                        'showTotals' => true,
                                        'sortOrder' => 'ASCENDING',
                                    ],
                                ],
                                'columns' => [
                                    [
                                        'sourceColumnOffset' => 4,
                                        'sortOrder' => 'ASCENDING',
                                        'showTotals' => true,
                                    ]
                                ],
                                'values' => [
                                    [
                                        'summarizeFunction' => 'COUNTA',
                                        'sourceColumnOffset' => 4
                                        ]
                                    ],
                                'valueLayout' => 'HORIZONTAL'
                            ]
                        ]
                        ]
                ],
                'start' => [
                    'sheetId' => $targetSheetId,
                    'rowIndex' => 0,
                    'columnIndex' => 0
                ],
                'fields' => 'pivotTable'
            ]
        ];
        return $batchUpdateResponse;
    }
        catch(Exception $e) {
            // TODO(developer) - handle error appropriately
            echo 'Message: ' .$e->getMessage();
        }
    }

Python

sheets/snippets/sheets_pivot_tables.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def pivot_tables(spreadsheet_id):
  """
  Creates the batch_update the user has access to.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member
  try:
    service = build("sheets", "v4", credentials=creds)
    # Create two sheets for our pivot table.
    body = {"requests": [{"addSheet": {}}, {"addSheet": {}}]}
    batch_update_response = (
        service.spreadsheets()
        .batchUpdate(spreadsheetId=spreadsheet_id, body=body)
        .execute()
    )
    source_sheet_id = (
        batch_update_response.get("replies")[0]
        .get("addSheet")
        .get("properties")
        .get("sheetId")
    )
    target_sheet_id = (
        batch_update_response.get("replies")[1]
        .get("addSheet")
        .get("properties")
        .get("sheetId")
    )
    requests = []
    requests.append(
        {
            "updateCells": {
                "rows": {
                    "values": [
                        {
                            "pivotTable": {
                                "source": {
                                    "sheetId": source_sheet_id,
                                    "startRowIndex": 0,
                                    "startColumnIndex": 0,
                                    "endRowIndex": 20,
                                    "endColumnIndex": 7,
                                },
                                "rows": [
                                    {
                                        "sourceColumnOffset": 1,
                                        "showTotals": True,
                                        "sortOrder": "ASCENDING",
                                    },
                                ],
                                "columns": [{
                                    "sourceColumnOffset": 4,
                                    "sortOrder": "ASCENDING",
                                    "showTotals": True,
                                }],
                                "values": [{
                                    "summarizeFunction": "COUNTA",
                                    "sourceColumnOffset": 4,
                                }],
                                "valueLayout": "HORIZONTAL",
                            }
                        }
                    ]
                },
                "start": {
                    "sheetId": target_sheet_id,
                    "rowIndex": 0,
                    "columnIndex": 0,
                },
                "fields": "pivotTable",
            }
        }
    )
    body = {"requests": requests}
    response = (
        service.spreadsheets()
        .batchUpdate(spreadsheetId=spreadsheet_id, body=body)
        .execute()
    )
    return response

  except HttpError as error:
    print(f"An error occurred: {error}")
    return error


if __name__ == "__main__":
  # Pass: spreadsheet_id
  pivot_tables("1CM29gwKIzeXsAppeNwrc8lbYaVMmUclprLuLYuHog4k")

Ruby

sheets/snippets/lib/spreadsheet_snippets.rb
requests = [{
  update_cells: {
    rows:   {
      values: [
        {
          pivot_table: {
            source:       {
              sheet_id:           source_sheet_id,
              start_row_index:    0,
              start_column_index: 0,
              end_row_index:      20,
              end_column_index:   7
            },
            rows:         [
              {
                source_column_offset: 1,
                show_totals:          true,
                sort_order:           'ASCENDING',
              },
            ],
            columns:      [
              {
                source_column_offset: 4,
                sort_order:           'ASCENDING',
                show_totals:          true,
              }
            ],
            values:       [
              {
                summarize_function:   'COUNTA',
                source_column_offset: 4
              }
            ],
            value_layout: 'HORIZONTAL'
          }
        }
      ]
    },
    start:  {
      sheet_id:     target_sheet_id,
      row_index:    0,
      column_index: 0
    },
    fields: 'pivotTable'
  }
}]
result = service.batch_update_spreadsheet(spreadsheet_id, body, {})