Je développe un Python 2.7
script qui analyse les données d'une table SQL et à la fin, génère un fichier CSV.
Une fois le fichier généré, je me connecte à mon compte Google Sheet et j'utilise l'option d'importation pour importer mon fichier CSV dans la feuille de calcul Google
Le travail manuel est un peu stupide et je souhaite ajouter cette capacité à mon script.
J'ai donc suivi ce guide Python Quickstart et j'ai pu terminer toutes les étapes.
Ensuite, j'ai suivi référence de l'API Google Sheets et j'ai examiné méthode: spreadsheets.create . Si je comprends bien, il ne fournit pas les options d'importation à partir d'un fichier.
Il semble qu'il n'y ait pas d'API pour la fonctionnalité d'importation.
Comment importer un fichier CSV à l'aide de l'API Google Sheets V4? Est-ce un exemple/référence qui me manque?
Une autre alternative à la réponse de Sam Berlin. Si vous utilisez Python, vous pouvez utiliser l'API Drive via gspread pour importer un fichier CSV. Voici un exemple:
import gspread
# Check how to get `credentials`:
# https://github.com/burnash/gspread
gc = gspread.authorize(credentials)
# Read CSV file contents
content = open('file_to_import.csv', 'r').read()
gc.import_csv('<SPREADSHEET_ID>', content)
Question connexe: Importer un fichier CSV dans Google Sheets à l'aide de gspread
Vous avez deux options pour importer un fichier g CSV. Vous pouvez utiliser API Drive pour créer une feuille de calcul à partir d'un CSV, ou vous pouvez utiliser l'API Sheets pour créer une feuille de calcul vide, puis utiliser spreadsheets.batchUpdate avec un PasteDataRequest pour ajouter des données CSV.
J'aime la bibliothèque gspread de Burnash, mais le import_csv
la fonction dans sa réponse est limitée. Il commence toujours la pâte à A1
de la première feuille de calcul (onglet) et supprime tous les autres onglets .
Je devais coller à partir d'un onglet et d'une cellule particuliers, j'ai donc pris la suggestion de Sam Berlin d'utiliser un PasteDataRequest. Voici ma fonction:
def pasteCsv(csvFile, sheet, cell):
'''
csvFile - path to csv file to upload
sheet - a gspread.Spreadsheet object
cell - string giving starting cell, optionally including sheet/tab name
ex: 'A1', 'MySheet!C3', etc.
'''
if '!' in cell:
(tabName, cell) = cell.split('!')
wks = sheet.worksheet(tabName)
else:
wks = sheet.sheet1
(firstRow, firstColumn) = gspread.utils.a1_to_rowcol(cell)
with open(csvFile, 'r') as f:
csvContents = f.read()
body = {
'requests': [{
'pasteData': {
"coordinate": {
"sheetId": wks.id,
"rowIndex": firstRow-1,
"columnIndex": firstColumn-1,
},
"data": csvContents,
"type": 'PASTE_NORMAL',
"delimiter": ',',
}
}]
}
return sheet.batch_update(body)
Notez que j'ai utilisé une requête pasteData brute plutôt que le niveau supérieur update_cells
méthode pour tirer parti de la gestion automatique (correcte) par Google des données d'entrée contenant des chaînes entre guillemets, qui peuvent contenir des virgules non délimitantes.
J'ai passé quelques heures à essayer de faire fonctionner les autres réponses. Les bibliothèques n'expliquent pas bien l'authentification et ne fonctionnent pas avec la manière fournie par Google de gérer les informations d'identification. D'un autre côté, la réponse de Sam ne précise pas les détails de l'utilisation de l'API, ce qui peut parfois prêter à confusion. Voici donc une recette complète de téléchargement de fichiers CSV sur gSheets. Il utilise les réponses de Sam et de CapoChino ainsi que certaines de mes propres recherches.
credentials.json
sans étapes supplémentairesquickstart.py
peut facilement être adapté en authenticate.py
https://www.googleapis.com/auth/spreadsheets
J'espère que maintenant vous avez vos informations d'identification stockées, alors passons au code réel
import pickle
from googleapiclient.discovery import build
SPREADSHEET_ID = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms' # Get this one from the link in browser
worksheet_name = 'Sheet2'
path_to_csv = 'New Folder/much_data.csv'
path_to_credentials = 'Credentials/token.pickle'
# convenience routines
def find_sheet_id_by_name(sheet_name):
# ugly, but works
sheets_with_properties = API \
.spreadsheets() \
.get(spreadsheetId=SPREADSHEET_ID, fields='sheets.properties') \
.execute() \
.get('sheets')
for sheet in sheets_with_properties:
if 'title' in sheet['properties'].keys():
if sheet['properties']['title'] == sheet_name:
return sheet['properties']['sheetId']
def Push_csv_to_gsheet(csv_path, sheet_id):
with open(csv_path, 'r') as csv_file:
csvContents = csv_file.read()
body = {
'requests': [{
'pasteData': {
"coordinate": {
"sheetId": sheet_id,
"rowIndex": "0", # adapt this if you need different positioning
"columnIndex": "0", # adapt this if you need different positioning
},
"data": csvContents,
"type": 'PASTE_NORMAL',
"delimiter": ',',
}
}]
}
request = API.spreadsheets().batchUpdate(spreadsheetId=SPREADSHEET_ID, body=body)
response = request.execute()
return response
# upload
with open(path_to_credentials, 'rb') as token:
credentials = pickle.load(token)
API = build('sheets', 'v4', credentials=credentials)
Push_csv_to_gsheet(
csv_path=path_to_csv,
sheet_id=find_sheet_id_by_name(worksheet_name)
)
Une bonne chose à propos de l'utilisation directe de batchUpdate
est qu'elle télécharge des milliers de lignes en une seconde. À un niveau bas, gspread
fait de même et devrait être aussi performant. Il y a aussi gspread-pandas .
p.s. le code est testé avec python 3.5
, mais ce fil semble être le plus approprié pour le soumettre.
Une alternative à la réponse de Sam Berlin, vous pouvez transformer votre CSV en une liste de listes et le définir sur votre charge utile POST.
Une telle fonction ressemble à ceci:
def preprocess(table):
table.to_csv('pivoted.csv') # I use Pandas but use whatever you'd like
_file = open('pivoted.csv')
contents = _file.read()
array = contents.split('\n')
master_array = []
for row in array:
master_array.append(row.split(','))
return master_array
Ce tableau maître est jeté dans les éléments suivants:
body = {
'values': newValues
}
result2 = service.spreadsheets().values().update(spreadsheetId=spreadsheetId, range=rangeName + str(len(values) + start + 1), valueInputOption="USER_ENTERED", body=body).execute()
Cela fonctionne très bien pour moi.