#python #google-api #google-drive-api #google-sheets-api #google-api-python-client
Вопрос:
Я создал довольно простую программу, которая берет лист Google и преобразует его в файл CSV, а затем выплевывает указанный CSV в заданный каталог. Эта часть работает так, как задумывалось, но результат .CSV не имеет разрывов строк или новых строк, поэтому, когда он загружается в Excel, он читается как одна строка, rn
вместо новых строк.
В этой программе есть некоторые ненужные импортные и другие проблемы, но я просто еще не очистил их.
Вот программа:
# Package Imports
from __future__ import print_function
import re
import os.path
import io
import csv
import ctypes
import google.auth.exceptions
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from googleapiclient.http import MediaIoBaseDownload
# Function Runners (for test purposes)
# Other Programmable Strings
EXPORT_DIRECTORY = 'DIREC'
CREDS_DIRECTORY = 'DIREC'
GSHEET_ID = 'ID'
FILE_NAME = 'NAME' '.csv'
# When editing this URL, token.json MUST be deleted to reauthorize with Google.
SCOPES = 'https://www.googleapis.com/auth/drive'
# Define Global Variables
MessageBox = ctypes.windll.user32.MessageBoxW
def main():
creds = None
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If there are no (valid) credentials available, directs user to OAuth login through default browser.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
try:
creds.refresh(Request())
except google.auth.exceptions.RefreshError:
MessageBox(None, 'There was an error authorizing with Google. You will be redirected to a login page.', 'Google Sheet to CSV: Fatal Error', 0)
else:
flow = InstalledAppFlow.from_client_secrets_file(
'C:\UsersAeroGOneDriveDesktopSHEETSCSVcredentials.json', SCOPES) # Sometimes requires a specific path to credentials.json.
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
service = build('drive', 'v3', credentials=creds)
В основном все, что вам нужно посмотреть, — это эта часть ниже.
# Call the Drive v3 API and compile CSV file from provided ID
file_id = GSHEET_ID
request = service.files().export_media(fileId=file_id,
mimeType='text/csv')
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
print("Download %d%%." % int(status.progress() * 100))
fh.seek(0)
with open('C:\UsersAeroGOneDriveDesktopSHEETSCSV\' FILE_NAME, 'w', newline='rn') as f:
f.write(str(fh.read()))
f.close()
if __name__ == '__main__':
main()
Мне действительно нужна помощь здесь. В двух словах, то, что происходит, — это выходной CSV, который я получаю, это:
b’ ,Jurisdiction,SHIPPING_ID,Combined,JobTitle,Shipping_Address,City,State,Zip,Phone,Email,Bill to addresses,,JobTitle,Address,City,State,Zip,Phone,EmailrnDATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,,,,,,,,,rnDATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,,,,,,,,,rnDATA,DATA,DATA,DATA
вместо желаемого результата, который заключается в следующем:
b’ ,Jurisdiction,SHIPPING_ID,Combined,JobTitle,Shipping_Address,City,State,Zip,Phone,Email,Bill to addresses,,JobTitle,Address,City,State,Zip,Phone,Email DATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,,,,,,,,, DATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,DATA,,,,,,,,, DATA,DATA,DATA,DATA
Я понимаю rn
, что предполагается перевести на новую строку, но это не так. Я очень признателен за любую помощь или что-то, что поможет мне направить меня в правильном направлении. Я не против любого решения, даже если оно включает в себя какой-то обходной метод.
Ответ №1:
Это пример из документации. Я задаюсь вопросом, не связана ли проблема с тем, как вы записываете кусочки в файл.
file_id = '1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo'
request = drive_service.files().export_media(fileId=file_id,
mimeType='application/pdf')
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
print "Download %d%%." % int(status.progress() * 100)
Почему бы не пойти немного проще?
with open('C:\UsersAeroGOneDriveDesktopSHEETSCSV\' FILE_NAME, "wb") as f:
f.write(fh.getbuffer())
Комментарии:
1. Я ожидал, что проблема была в том, как байты записывались в файл, я просто понятия не имел, куда идти. Ваш подход сработал как заклинание. Большое вам спасибо, вы упростили код и исправили проблему, вы лучший.