Nachdem Sie einen Bericht identifiziert oder erstellt haben, der Ihren Anforderungen entspricht, ist es an der Zeit, eine Ausgabe zu generieren. Die Berichtsausgabe wird in Berichtsdateien gespeichert, die programmatisch abgerufen und bearbeitet werden können. Eine Reportdatei wird im Ergebnis der Berichterstellung erstellt.
In diesem Leitfaden erfahren Sie, wie Sie Berichtdateien mit dem Berichtsdienst programmatisch generieren können.
Bericht suchen
Um einen Bericht zu erstellen, müssen Sie die ID des Berichts kennen. Wenn Sie gerade einen Bericht erstellt oder aktualisiert haben, finden Sie diesen Wert im Feld id
der zurückgegebenen Berichtsressource. Es wird empfohlen, dass Nutzer diese zurückgegebenen IDs für eine spätere Suche speichern.
Wenn Sie die ID des zu erstellenden Berichts nicht kennen, können Sie in der Liste aller verfügbaren Berichte nach dem gewünschten Bericht suchen. Das folgende Beispiel zeigt, wie ein Bericht anhand bestimmter benutzerdefinierter Kriterien aufgerufen wird:
C#
Report target = null;
ReportList reports;
String nextPageToken = null;
do {
// Create and execute the reports list request.
ReportsResource.ListRequest request = service.Reports.List(profileId);
request.PageToken = nextPageToken;
reports = request.Execute();
foreach (Report report in reports.Items) {
if (IsTargetReport(report)) {
target = report;
break;
}
}
// Update the next page token.
nextPageToken = reports.NextPageToken;
} while (target == null
&& reports.Items.Any()
&& !String.IsNullOrEmpty(nextPageToken));
Java
Report target = null;
ReportList reports;
String nextPageToken = null;
do {
// Create and execute the reports list request.
reports = reporting.reports().list(profileId).setPageToken(nextPageToken).execute();
for (Report report : reports.getItems()) {
if (isTargetReport(report)) {
target = report;
break;
}
}
// Update the next page token.
nextPageToken = reports.getNextPageToken();
} while (target == null
&& !reports.getItems().isEmpty()
&& !Strings.isNullOrEmpty(nextPageToken));
PHP
$target = null;
$response = null;
$pageToken = null;
do {
// Create and execute the report list request.
$response = $this->service->reports->listReports(
$userProfileId,
['pageToken' => $pageToken]
);
foreach ($response->getItems() as $report) {
if ($this->isTargetReport($report)) {
$target = $report;
break;
}
}
$pageToken = $response->getNextPageToken();
} while (empty($target) && !empty($response->getItems()) && !empty($pageToken));
Python
target = None
# Construct the request.
request = service.reports().list(profileId=profile_id)
while True:
response = request.execute()
for report in response['items']:
if is_target_report(report):
target = report
break
if not target and response['items'] and response['nextPageToken']:
request = service.reports().list_next(request, response)
else:
break
Ruby
page_token = nil
target = nil
loop do
result = service.list_reports(profile_id, page_token: page_token)
result.items.each do |report|
if target_report?(report)
target = report
break
end
end
page_token = (result.next_page_token if target.nil? && result.items.any?)
break if page_token.to_s.empty?
end
In der Referenzdokumentation finden Sie optionale Parameter, mit denen Sie steuern können, wie die Liste der zurückgegebenen Berichte sortiert und sortiert wird. Die Steuerung der Sortierung und Reihenfolge dieser Liste kann besonders hilfreich sein, um Berichte zu finden, die kürzlich geändert wurden.
Bericht erstellen
Sobald Sie einen geeigneten Bericht gefunden haben, können Sie ihn mit dem Berichtdienst ausführen und eine neue Berichtsdatei erstellen. Berichte können entweder synchron oder asynchron (Standardeinstellung) erstellt werden, je nach Komplexität des Berichts und der Verarbeitungszeit. Weitere Informationen zur synchronen und asynchronen Berichterstellung erhalten Sie im Leitfaden zu synchronen Berichten.
Um einen Bericht zu erstellen, rufen Sie die run method des Berichtsdienstes auf, wie im folgenden Beispiel gezeigt:
C#
// Run the report.
File file = service.Reports.Run(profileId, reportId).Execute();
Java
// Run the report.
File file = reporting.reports().run(profileId, reportId).execute();
PHP
// Run the report.
$file = $this->service->reports->run($userProfileId, $reportId);
Python
# Run the report.
report_file = service.reports().run(
profileId=profile_id, reportId=report_id).execute()
Ruby
# Run the report.
report_file = service.run_report(profile_id, report_id)
Die Antwort auf diese Anfrage ist eine Ressource vom Typ Files. Bei einer erfolgreichen synchronen Ausführungsanfrage würden alle Felder der zurückgegebenen Ressource ausgefüllt und die Datei kann heruntergeladen werden. Da es sich hierbei um eine asynchrone Ausführungsanfrage handelt, fehlen jedoch bestimmte Schlüsselfelder und der status
der Datei wird auf PROCESSING
gesetzt, da der Bericht noch nicht vollständig ausgeführt wurde.
Wann ist die Erstellung eines Berichts abgeschlossen?
Wenn Sie einen Bericht asynchron ausführen, wird sofort eine Platzhalterdatei generiert und der Bericht zur Verarbeitung in eine Warteschlange gestellt. Der Platzhalter enthält zwei wichtige Informationen, anhand derer Sie feststellen können, wann der Bericht fertig erstellt ist:
- Ein
id
-Feld, mit dem in nachfolgenden Anfragen auf diese Datei verwiesen werden kann. - Ein
status
-Feld, das den aktuellen Status der Berichtsausführung darstellt.
Um festzustellen, wann ein Bericht vollständig ausgeführt wurde, müssen Sie regelmäßig den status
der Datei prüfen, wie im folgenden Beispiel gezeigt:
C#
// Wait for the report file to finish processing.
// An exponential backoff policy is used to limit retries and conserve quota.
int sleep = 0;
int startTime = GetCurrentTimeInSeconds();
do {
File file = service.Files.Get(reportId, fileId).Execute();
if ("REPORT_AVAILABLE".Equals(file.Status)) {
Console.WriteLine("File status is {0}, ready to download.", file.Status);
return;
} else if (!"PROCESSING".Equals(file.Status)) {
Console.WriteLine("File status is {0}, processing failed.", file.Status);
return;
} else if (GetCurrentTimeInSeconds() - startTime > MAX_RETRY_ELAPSED_TIME) {
Console.WriteLine("File processing deadline exceeded.");
return;
}
sleep = GetNextSleepInterval(sleep);
Console.WriteLine("File status is {0}, sleeping for {1} seconds.", file.Status, sleep);
Thread.Sleep(sleep * 1000);
} while (true);
Java
BackOff backOff =
new ExponentialBackOff.Builder()
.setInitialIntervalMillis(10 * 1000) // 10 second initial retry
.setMaxIntervalMillis(10 * 60 * 1000) // 10 minute maximum retry
.setMaxElapsedTimeMillis(60 * 60 * 1000) // 1 hour total retry
.build();
do {
File file = reporting.files().get(reportId, fileId).execute();
if ("REPORT_AVAILABLE".equals(file.getStatus())) {
// File has finished processing.
System.out.printf("File status is %s, ready to download.%n", file.getStatus());
return file;
} else if (!"PROCESSING".equals(file.getStatus())) {
// File failed to process.
System.out.printf("File status is %s, processing failed.", file.getStatus());
return null;
}
// The file hasn't finished processing yet, wait before checking again.
long retryInterval = backOff.nextBackOffMillis();
if (retryInterval == BackOff.STOP) {
System.out.println("File processing deadline exceeded.%n");
return null;
}
System.out.printf("File status is %s, sleeping for %dms.%n", file.getStatus(), retryInterval);
Thread.sleep(retryInterval);
} while (true);
PHP
// Wait for the report file to finish processing.
// An exponential backoff policy is used to limit retries and conserve
// quota.
$sleep = 0;
$startTime = time();
do {
$file = $this->service->files->get($reportId, $fileId);
if ($file->getStatus() === 'REPORT_AVAILABLE') {
printf('File status is %s, ready to download<br>', $file->getStatus());
return $file;
} elseif ($file->getStatus() !== 'PROCESSING') {
printf('File status is %s, processing failed<br>', $file->getStatus());
return null;
} elseif (time() - $startTime > self::MAX_RETRY_ELAPSED_TIME) {
printf('File processing deadline exceeded<br>');
return null;
}
$sleep = $this->getNextSleepInterval($sleep);
printf(
'File status is %s, sleeping for %d seconds<br>',
$file->getStatus(),
$sleep
);
$this->sleep($sleep);
} while (true);
Python
# Wait for the report file to finish processing.
# An exponential backoff strategy is used to conserve request quota.
sleep = 0
start_time = time.time()
while True:
report_file = service.files().get(
reportId=report_id, fileId=file_id).execute()
status = report_file['status']
if status == 'REPORT_AVAILABLE':
print 'File status is %s, ready to download.' % status
return
elif status != 'PROCESSING':
print 'File status is %s, processing failed.' % status
return
elif time.time() - start_time > MAX_RETRY_ELAPSED_TIME:
print 'File processing deadline exceeded.'
return
sleep = next_sleep_interval(sleep)
print 'File status is %s, sleeping for %d seconds.' % (status, sleep)
time.sleep(sleep)
Ruby
# Wait for the report file to finish processing.
# An exponential backoff strategy is used to conserve request quota.
interval = 0
start_time = Time.now
loop do
report_file = service.get_file(report_id, file_id)
status = report_file.status
if status == 'REPORT_AVAILABLE'
puts format('File status is %s, ready to download.', status)
break
elsif status != 'PROCESSING'
puts format('File status is %s, processing failed.', status)
break
elsif Time.now - start_time > MAX_RETRY_ELAPSED_TIME
puts 'File processing deadline exceeded.'
break
end
interval = next_sleep_interval(interval)
puts format('File status is %s, sleeping for %d seconds.', status,
interval)
sleep(interval)
end
Wenn sich status
zu REPORT_AVAILABLE
ändert, kann die Datei heruntergeladen werden. Wie im obigen Beispiel gezeigt, wird dringend empfohlen, für solche Abfragen eine Strategie mit exponentiellem Backoff zu implementieren, um die Nutzung Ihres Anfragekontingents zu optimieren.