Comenzando con Google Sheets en Python. Desde el registro hasta la lectura de datos

Durante bastante tiempo logré subir datos a Excel, pero el mod está cambiando, los usuarios lo quieren en las nubes.

Después de comenzar a traducir varios proyectos a Python, decidí que era hora de cambiar (o agregar) Excel con algo más moderno.

Cuando descubrí por primera vez la necesidad de trabajar con las hojas de cálculo de Google de Python, tenía la ilusión de que todo esto se puede hacer con un par de clics. La realidad resultó ser menos optimista, pero no tenemos otro globo.

Los artículos me ayudaron mucho:


Como de costumbre, cuando tomas algo por primera vez, te enfrentas a una gran cantidad de preguntas que luego solo causan desconcierto: ¿cómo podría alguien siquiera pensar en esto? Elemental!

Tal vez solo he caminado un largo camino; me alegrará que me corrija.

Todas las acciones se realizaron en una computadora con Windows + Python 3.6.6, y también se usó un Jupyter Notebook.

Las principales dificultades que tuve en la etapa de ajustes preliminares. Encontrar un código viable no es difícil.

El código utilizado en el artículo está disponible en el repositorio.

Regístrese para los servicios de Google e instale bibliotecas


Para trabajar con tablas, debe registrarse en Google, configurar el proyecto e instalar las bibliotecas necesarias.

La documentación oficial en inglés está aquí .

Primero debe registrarse en gmail.com (puede hacerlo usted mismo). Luego debe crear un proyecto (ya que Google proporciona acceso a sus servicios).

Este es un proceso largo y tedioso que le permite comprender por qué las interfaces de Google no se consideran las más convenientes e intuitivas (algunos creen que la red social Google+ no despegó por este motivo).

Para hacer esto, vaya a console.developers.google.com/cloud-resource-manager y haga clic en "Crear proyecto"



Ingrese el nombre del proyecto y haga clic en "Crear"



En la lista actualizada de proyectos, vaya al menú "Permisos"


En la ventana que se abre, haga clic en "Agregar", ingrese su dirección de correo electrónico del dominio gmail.com y seleccione el grupo "Proyecto" - "Propietario"



Guarda los cambios.

Puede parecer extraño que haya creado un proyecto pero se ve obligado a emitir derechos para usted. Y esto es realmente extraño, pero era un camino que había que tomar al momento de escribir este curso, para que todo comenzara a funcionar como debería.

Visite console.developers.google.com/cloud-resource-manager nuevamente

Seleccione el menú de configuración en su proyecto



En la ventana que se abre, seleccione "Cuentas de servicio" y luego "Crear una cuenta de servicio"



Ingrese el nombre de la cuenta y haga clic en "Crear"



Seleccione el rol Propietario y haga clic en Continuar.



En la ventana que aparece, haga clic en Crear clave



Seleccione el tipo de clave json y haga clic en Crear



Se creará un archivo con claves y se descargará inmediatamente. Guárdelo, gracias a él podremos acceder a los servicios de Google.

Haga clic en el botón con tres trazos horizontales, a la izquierda de la inscripción "API de Google", seleccione "API y servicios", y en él el subelemento "Panel de control".



En la ventana que se abre, haga clic en "Habilitar API y servicios"



Escriba "google drive" en la barra de búsqueda y haga clic en el servicio "Google Drive API"



Haz clic en Habilitar



El sitio le notificará que la API está habilitada y le advertirá que se deben crear las credenciales. Ignore esta advertencia (ya hemos creado una cuenta de servicio).



Regrese al panel de control.



En la ventana que se abre, haga clic en "Habilitar API y servicios"



Introduzca "hoja" en la barra de búsqueda y haga clic en el servicio "API de Hojas de cálculo de Google"



Asegúrese de que esta API esté conectada. Debería encenderse automáticamente cuando conecte la API de Google Drive. Si está conectado, verá el botón "Administrar API", si no, el botón "Activar". Enciéndelo si es necesario.

La última vez, visite console.developers.google.com/cloud-resource-manager

Seleccione el menú de configuración en su proyecto


En la ventana que se abre, seleccione "Cuentas de servicio" y luego copie y guarde la dirección de correo electrónico de la cuenta de servicio. Le resultará útil dar acceso a las tablas.



Ahora procedemos a la instalación de bibliotecas. Ejecute el comando en la consola

pip3 install --upgrade google-api-python-client 

y luego

 pip3 install oauth2client 

Es posible que cuando ejecute el segundo comando, reciba un mensaje de que la biblioteca oauth2client ya está instalada.

Vaya a raw.githubusercontent.com/gsuitedevs/python-samples/master/sheets/quickstart/quickstart.py

Presione el botón derecho del mouse y seleccione "Guardar como"



Guarde el archivo como quickstart.py

y ejecutarlo con el comando

 python quickstart.py 

Se abrirá una nueva página en el navegador (tal vez dirá que la página no es segura, pero valientemente continúe) y tendrá que aceptar las condiciones.

En esto nuestro camino se completa.

Llenando y formateando una tabla


Crea la primera tabla

 #   import httplib2 import apiclient.discovery from oauth2client.service_account import ServiceAccountCredentials CREDENTIALS_FILE = 'seraphic-effect-248407-7ac2c44ec709.json' #     ,     #     credentials = ServiceAccountCredentials.from_json_keyfile_name(CREDENTIALS_FILE, ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive']) httpAuth = credentials.authorize(httplib2.Http()) #    service = apiclient.discovery.build('sheets', 'v4', http = httpAuth) #      4  API spreadsheet = service.spreadsheets().create(body = { 'properties': {'title': '  ', 'locale': 'ru_RU'}, 'sheets': [{'properties': {'sheetType': 'GRID', 'sheetId': 0, 'title': '  ', 'gridProperties': {'rowCount': 100, 'columnCount': 15}}}] }).execute() spreadsheetId = spreadsheet['spreadsheetId'] #    print('https://docs.google.com/spreadsheets/d/' + spreadsheetId) 

Si todo salió sin errores, se mostrará un enlace a la tabla.

El identificador de archivo se usa en este enlace, lo guardamos en la variable spreadsheetId y lo usaremos en el futuro.

Síguelo Google le informará que no tiene acceso



¡No solicites permiso! Recibirá una notificación de que no es posible enviar una carta de solicitud a la dirección que Google mismo asignó a la cuenta del sistema. Pero no puedes cambiar esta dirección. Quizás esto no funcione solo en modo libre.

Pero podemos darnos acceso a través de Google Drive. Debe reemplazar my_test_address@gmail.com por el suyo.

 driveService = apiclient.discovery.build('drive', 'v3', http = httpAuth) #    Google Drive  3  API access = driveService.permissions().create( fileId = spreadsheetId, body = {'type': 'user', 'role': 'writer', 'emailAddress': 'my_test_address@gmail.com'}, #     fields = 'id' ).execute() 

Ahora tiene acceso, no cierre la tabla, lo gestionaremos e inmediatamente analizaremos los cambios.

Cada documento tiene su propio código, spreadsheetId, que es exactamente lo que se muestra en la barra de direcciones cuando abrimos la tabla en el navegador (en la URL de la página con la tabla abierta, está entre "https://docs.google.com/spreadsheets/d/" y "/ edit # gid = 0").

Lo guardamos en la variable spreadsheetId y continuaremos trabajando con él.

Primero, una pequeña teoría.

En cada archivo (hoja de cálculo) hay fichas de hojas (hoja).

Cada hoja tiene su propio código numérico (sheetId). La primera hoja creada en el documento tiene este Id igual a 0. Las hojas restantes tienen un ID distinto de cero muy diferente (es decir, no están numeradas consecutivamente).

Asegúrate de esto

 #   results = service.spreadsheets().batchUpdate( spreadsheetId = spreadsheetId, body = { "requests": [ { "addSheet": { "properties": { "title": "  ", "gridProperties": { "rowCount": 20, "columnCount": 12 } } } } ] }).execute() #   ,  Id   spreadsheet = service.spreadsheets().get(spreadsheetId = spreadsheetId).execute() sheetList = spreadsheet.get('sheets') for sheet in sheetList: print(sheet['properties']['sheetId'], sheet['properties']['title']) sheetId = sheetList[0]['properties']['sheetId'] print('     Id = ', sheetId) 

Algo como esto aparecerá en la pantalla:

0 Hoja número uno
415832263 Otra hoja
Usaremos una hoja con Id = 0


De hecho, la primera hoja tiene un Id de cero, y la segunda tiene un número diferente.

Una pregunta más: cómo especificar rangos de celdas. Aparentemente, las hojas de cálculo de Google fueron desarrolladas por diferentes equipos, bajo la guía de diferentes gerentes y con la ayuda de diferentes arquitectos. Porque las coordenadas de las celdas se establecen de dos maneras diferentes.

Opción 1: en el formato de texto "Hoja número uno! B2: D5", es decir el nombre de la hoja, seguido de un signo de exclamación, después de - la celda superior izquierda en el formato "letra (columna) + número (cadena)" + la celda inferior derecha en el mismo formato.

 {"range": "  !B2:D5"} 

Opción 2: en formato json, que indica la ID de la hoja y las coordenadas de las celdas superior izquierda e inferior derecha en forma numérica (número de fila y número de columna)

 {"range": { "sheetId": sheetId, # ID  "startRowIndex": 1, #    startRowIndex "endRowIndex": 5,#  endRowIndex - 1 (endRowIndex  !) "startColumnIndex": 0, #    startColumnIndex "endColumnIndex": 1 #  endColumnIndex - 1 }} 

Las diferentes funciones usan diferentes formatos.

Ahora sabemos lo suficiente como para llenar las celdas con datos, dibujar un marco y resaltar los encabezados.

 results = service.spreadsheets().values().batchUpdate(spreadsheetId = spreadsheetId, body = { "valueInputOption": "USER_ENTERED", #  ,    (  ) "data": [ {"range": "  !B2:D5", "majorDimension": "ROWS", #   ,   "values": [ [" B2", " C2", " D2"], #    ['25', "=6*6", "=sin(3,14/2)"] #    ]} ] }).execute() 

Rellene varias celdas con datos. Porque se especifica el parámetro USER_ENTERED, la tabla percibe estos datos como percibiría la entrada del usuario: convierte los valores numéricos en números y los valores que comienzan con el signo igual en fórmulas.

Mira tu tabla, está llena de datos



Establecer el ancho de columna. La función batchUpdate puede aceptar varios comandos a la vez, por lo que estableceremos el ancho de tres grupos de columnas con una sola solicitud. Hay una columna en el primer y tercer grupo, y dos en el segundo.

 results = service.spreadsheets().batchUpdate(spreadsheetId = spreadsheetId, body = { "requests": [ #    A: 20  { "updateDimensionProperties": { "range": { "sheetId": sheetId, "dimension": "COLUMNS", #    "startIndex": 0, #     "endIndex": 1 #    startIndex  endIndex - 1 (endIndex  !) }, "properties": { "pixelSize": 20 #    }, "fields": "pixelSize" # ,     pixelSize } }, #    B  C: 150  { "updateDimensionProperties": { "range": { "sheetId": sheetId, "dimension": "COLUMNS", "startIndex": 1, "endIndex": 3 }, "properties": { "pixelSize": 150 }, "fields": "pixelSize" } }, #    D: 200  { "updateDimensionProperties": { "range": { "sheetId": sheetId, "dimension": "COLUMNS", "startIndex": 3, "endIndex": 4 }, "properties": { "pixelSize": 200 }, "fields": "pixelSize" } } ] }).execute() 

Mire la tabla, los anchos de columna han cambiado.



Dibuja un marco alrededor de la mesa

 #   results = service.spreadsheets().batchUpdate( spreadsheetId = spreadsheetId, body = { "requests": [ {'updateBorders': {'range': {'sheetId': sheetId, 'startRowIndex': 1, 'endRowIndex': 3, 'startColumnIndex': 1, 'endColumnIndex': 4}, 'bottom': { #      'style': 'SOLID', #   'width': 1, #  1  'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}}, #   'top': { #      'style': 'SOLID', 'width': 1, 'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}}, 'left': { #      'style': 'SOLID', 'width': 1, 'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}}, 'right': { #      'style': 'SOLID', 'width': 1, 'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}}, 'innerHorizontal': { #       'style': 'SOLID', 'width': 1, 'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}}, 'innerVertical': { #       'style': 'SOLID', 'width': 1, 'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}} }} ] }).execute() 



Combina las celdas sobre la tabla e ingresa el título en ellas.

 #   A2:D1 results = service.spreadsheets().batchUpdate( spreadsheetId = spreadsheetId, body = { "requests": [ {'mergeCells': {'range': {'sheetId': sheetId, 'startRowIndex': 0, 'endRowIndex': 1, 'startColumnIndex': 1, 'endColumnIndex': 4}, 'mergeType': 'MERGE_ALL'}} ] }).execute() #    results = service.spreadsheets().values().batchUpdate(spreadsheetId = spreadsheetId, body = { "valueInputOption": "USER_ENTERED", #  ,    (  ) "data": [ {"range": "  !B1", "majorDimension": "ROWS", #   ,   "values": [[" " ] ]} ] }).execute() 



Establecer el formato para las celdas del encabezado de la tabla

 #    results = service.spreadsheets().batchUpdate( spreadsheetId = spreadsheetId, body = { "requests": [ { "repeatCell": { "cell": { "userEnteredFormat": { "horizontalAlignment": 'CENTER', "backgroundColor": { "red": 0.8, "green": 0.8, "blue": 0.8, "alpha": 1 }, "textFormat": { "bold": True, "fontSize": 14 } } }, "range": { "sheetId": sheetId, "startRowIndex": 1, "endRowIndex": 2, "startColumnIndex": 1, "endColumnIndex": 4 }, "fields": "userEnteredFormat" } } ] }).execute() 



Hay una manera fácil de averiguar qué ancho o color necesita establecer una celda. Para hacer esto, es suficiente formatear manualmente una de las celdas y leer sus propiedades.

 ranges = ["  !C2:C2"] # results = service.spreadsheets().get(spreadsheetId = spreadsheetId, ranges = ranges, includeGridData = True).execute() print(' ') print(results['properties']) print('\n  ') print(results['sheets'][0]['data'][0]['rowData'] ) print('\n ') print(results['sheets'][0]['data'][0]['rowMetadata']) print('\n ') print(results['sheets'][0]['data'][0]['columnMetadata']) 

Nos ponemos en respuesta
Datos maestros
{'title': 'Primer documento de prueba', 'locale': 'ru_RU', 'autoRecalc': 'ON_CHANGE', 'timeZone': 'Etc / GMT', 'defaultFormat': {'backgroundColor': {'red' : 1, 'verde': 1, 'azul': 1}, 'relleno': {'arriba': 2, 'derecha': 3, 'abajo': 2, 'izquierda': 3}, 'verticalAlignment': 'BOTTOM', 'wrapStrategy': 'OVERFLOW_CELL', 'textFormat': {'foregroundColor': {}, 'fontFamily': 'arial, sans, sans-serif', 'fontSize': 10, 'bold': False, 'cursiva': falso, 'tachado': falso, 'subrayado': falso}}}

Valores y coloración
[{'valores': [{'userEnteredValue': {'stringValue': 'Cell C2'}, 'efectivoValue': {'stringValue': 'Cell C2'}, 'formattedValue': 'Cell C2', 'userEnteredFormat' : {'backgroundColor': {'red': 1, 'green': 0.6}, 'horizontalAlignment': 'CENTER', 'textFormat': {'fontSize': 14, 'bold': True, 'italic': True }}, 'efectivoFormato': {'backgroundColor': {'rojo': 1, 'verde': 0.6}, 'relleno': {'superior': 2, 'derecho': 3, 'inferior': 2, ' left ': 3},' horizontalAlignment ':' CENTER ',' verticalAlignment ':' BOTTOM ',' wrapStrategy ':' OVERFLOW_CELL ',' textFormat ': {' foregroundColor ': {},' fontFamily ':' Arial ', 'fontSize': 14, 'bold': True, 'italic': True, 'tachado': False, 'subrayado': False}, 'hyperlinkDisplayType': 'PLAIN_TEXT'}}]}]]

Altura de la celda
[{'pixelSize': 21}]

Ancho de la celda
[{'pixelSize': 150}]
Este código mostrará las propiedades de la celda C2. Puede seleccionar la fuente y el color de relleno manualmente (en la tabla), luego ver cómo se reflejan en json.

Leer datos de una tabla


Para revelar completamente las características de la lectura de datos, llené manualmente las celdas B4, C7 y D5 como se muestra en la figura.



Código para leer datos

 ranges = ["  !A2:F8"] # results = service.spreadsheets().values().batchGet(spreadsheetId = spreadsheetId, ranges = ranges, valueRenderOption = 'FORMATTED_VALUE', dateTimeRenderOption = 'FORMATTED_STRING').execute() sheet_values = results['valueRanges'][0]['values'] print(sheet_values) 

Resultado
[['', 'Celda B2', 'Celda C2', 'Celda D2'], ['', '25', '36', '0,9999996829']]

Algunos parámetros de la función: valueRenderOption - formato para leer datos numéricos.

  • FORMATTED_VALUE : lectura basada en el formato de visualización. Es decir lo que estaba visible en la tabla será leído. Por ejemplo, en la celda D3, el número es 0.9999999, pero el formato es "dos decimales", por lo que se muestra "1.00", es en este formato que se leerá.
  • UNFORMATTED_VALUE : se lee el contenido de la celda, no se tiene en cuenta el formato (es decir, se leería 0.9999999)
  • FÓRMULA : se muestra la fórmula (en este caso “= sin (3,14 / 2)”. Si se ingresa un número en la celda, en este modo se leerá.

Este código lee los datos y los muestra línea por línea. Rango legible A2: F8.
Como se ve en la pantalla:

  • Si no se llena ninguna celda en la línea que se está leyendo, no se muestran los datos en la línea.
  • Los datos después de la última celda llena no se muestran.

Source: https://habr.com/ru/post/483302/


All Articles