Alexander Lucas, Tim Google Analytics API – Agustus 2010
Pengantar
Artikel ini menunjukkan cara mengambil data dari kueri apa pun yang dibuat ke Data Export API Google Analytics dan menampilkan hasilnya dalam format CSV yang populer. Ini adalah salah satu tugas paling umum yang dilakukan pengguna dengan data Analytics yang diambil dari Data Export API, sehingga mengotomatiskan proses ini merupakan cara mudah untuk menghemat banyak waktu secara rutin. Selain itu, setelah Anda memiliki kode untuk mencetak dokumen CSV dari kueri, Anda dapat mengintegrasikannya ke dalam project yang lebih besar, seperti pembuat laporan otomatis, surat, dan fungsi "ekspor" untuk dasbor kustom yang telah Anda tulis.
Sebelum Memulai
Anda dapat mengoptimalkan artikel ini jika memiliki hal berikut:
- Pengetahuan tentang Java.
- Pengetahuan tentang Google Analytics, termasuk pemahaman tentang dimensi dan metrik.
- Akses ke akun Google Analytics aktif dengan data yang sebenarnya.
- Memahami Panduan Memulai Java Data Export API. Artikel ini mengasumsikan bahwa Anda sudah mengetahui semua hal yang dibahas dalam panduan tersebut.
- Salinan lokal kode sumber lengkap, yang bisa Anda dapatkan di AnalyticsCvsPrinter.java. Contoh aplikasi yang menggunakan kode ini dapat ditemukan di AnalyticsCsvDemo.java.
Ringkasan Program
Kode yang dibahas dalam artikel ini akan berfungsi sebagai berikut:
- Mengaktifkan pemilihan pada saat runtime, apakah kode dicetak ke konsol atau ke aliran file.
- Dengan objek
DataFeed
sebagai parameter, cetak data tersebut dalam format CSV:- Cetak header baris.
- Mencetak baris data, dengan setiap
DataEntry
membentuk satu baris dalam output yang dihasilkan. - Jalankan setiap nilai melalui metode sanitasi untuk output yang aman dari CSV.
- Tulis metode "Sanitizer" yang membuat semua input Aman untuk CSV.
- Memberi Anda class Java yang dapat mengambil kueri Data Export API apa pun dan mengubahnya menjadi file CSV.
Izinkan Aliran Output yang Dapat Dikonfigurasi
Hal pertama yang harus dilakukan adalah menyiapkan streaming output yang dapat dikonfigurasi untuk
menjadi tujuan pencetakan class Anda. Dengan demikian, kode apa pun yang menggunakan class Anda dapat menentukan apakah output harus dikirim ke
standard out atau langsung ke file. Yang perlu Anda lakukan di sini adalah menyiapkan metode pengambil/penyetel
untuk objek PrintStream
. Itu akan menjadi target dari semua
pencetakan yang dilakukan oleh class tersebut.
private PrintStream printStream = System.out; public PrintStream getPrintStream() { return printStream; } public void setPrintStream(PrintStream printStream) { this.printStream = printStream; }
Menyetel {i>output<i} ke file juga sangat mudah. Kita hanya memerlukan nama file
untuk membuat objek PrintStream
bagi file tersebut.
FileOutputStream fstream = new FileOutputStream(filename); PrintStream stream = new PrintStream(fstream); csvprinter.setPrintStream(stream);
Melakukan iterasi melalui data
Baris pertama {i>file<i} CSV adalah baris nama kolom. Setiap kolom mewakili dimensi atau metrik dari feed data, jadi untuk mencetak baris pertama ini, lakukan hal berikut.
- Ambil entri pertama dari feed.
- Lakukan iterasi melalui daftar dimensi menggunakan metode
getDimensions
entri tersebut. - Cetak nama setiap dimensi menggunakan metode
Dimension.getName()
, diikuti dengan koma. - Lakukan hal yang sama untuk metrik menggunakan metode
getMetrics()
. Setelah semua, cetak koma, kecuali metrik terakhir.
Berikut salah satu implementasi metode untuk mencetak header baris. Perlu diperhatikan bahwa kode ini tidak menampilkan string yang mewakili baris lengkap: kode ini dicetak ke aliran output saat memproses nilai.
public void printRowHeaders(DataFeed feed) { if(feed.getEntries().size() == 0) { return; } DataEntry firstEntry = feed.getEntries().get(0); Iterator<Dimension> dimensions = firstEntry.getDimensions().iterator(); while (dimensions.hasNext()) { printStream.print(sanitizeForCsv(dimensions.next().getName())); printStream.print(","); } Iterator<Metric> metrics = firstEntry.getMetrics().iterator(); while (metrics.hasNext()) { printStream.print(sanitizeForCsv(metrics.next().getName())); if (metrics.hasNext()) { printStream.print(","); } } printStream.println(); }
Mencetak "isi" file CSV (semua yang ada di bawah baris nama
kolom) sangat mirip. Hanya ada dua perbedaan utama. Pertama, itu bukan hanya
entri pertama yang dievaluasi. Kode harus melakukan loop melalui semua entri dalam objek feed. Kedua, daripada menggunakan metode getName()
untuk menarik nilai yang akan dibersihkan dan dicetak, gunakan
getValue()
sebagai gantinya.
public void printBody(DataFeed feed) { if(feed.getEntries().size() == 0) { return; } for (DataEntry entry : feed.getEntries()) { printEntry(entry); } } public void printEntry(DataEntry entry) { Iterator<Dimension> dimensions = entry.getDimensions().iterator(); while (dimensions.hasNext()) { printStream.print(sanitizeForCsv(dimensions.next().getValue())); printStream.print(","); } Iterator<Metric> metrics = entry.getMetrics().iterator(); while (metrics.hasNext()) { printStream.print(sanitizeForCsv(metrics.next().getValue())); if (metrics.hasNext()) { printStream.print(","); } } printStream.println(); }
Kode ini membagi feed Anda menjadi beberapa entri, dan entri Anda menjadi nilai yang akan dicetak menjadi output. Namun, bagaimana cara membuat nilai tersebut ramah untuk CSV? Bagaimana jika nilai dalam file "nilai yang dipisahkan koma" memiliki tanda koma di dalamnya? Nilai-nilai tersebut harus dibersihkan.
Cara Membersihkan Data untuk Kompatibilitas CSV
CSV adalah format yang sederhana. {i>File<i} CSV mewakili tabel data, dan setiap baris mewakili baris dalam tabel itu. Nilai-nilai di baris tersebut dipisahkan dengan tanda koma. Baris baru berarti baris data baru.
Sayangnya, format yang sederhana ini membuat pengguna dapat dengan mudah membuang data yang buruk. Bagaimana jika nilai Anda memiliki koma di dalamnya? Bagaimana jika salah satu nilai Anda memiliki jeda baris di dalamnya? Apa yang harus terjadi dengan spasi antara koma dan nilai? Semua situasi ini dapat diperhitungkan karena menggunakan beberapa aturan sederhana.
- Jika string berisi karakter kutip ganda, konversikan dengan karakter kutip ganda kedua.
- Jika ada koma dalam string, gabungkan seluruh string dengan tanda kutip ganda (kecuali jika Anda sudah memilikinya).
- Jika ada jeda baris dalam string, gabungkan seluruh string dengan tanda kutip ganda (kecuali jika Anda sudah memilikinya).
- Jika string dimulai atau diakhiri dengan spasi kosong, gabungkan seluruh string dalam tanda kutip ganda (kecuali jika Anda sudah memilikinya).
Mungkin sedikit sulit untuk memvisualisasikan tampilan nilai Anda pada tahap ini, jadi berikut beberapa contohnya. Ingat, setiap contoh mewakili nilai tunggal, dan di-escape seperti itu. Untuk kejelasan, spasi akan ditampilkan sebagai karakter _.
Sebelum | Setelah |
---|---|
tidak diubah | tidak diubah |
kutipan " acak | tanda kutip ganda "" acak |
koma,terpisah | "koma,dipisahkan" |
Dua baris |
"Dua baris" |
_spasi di awal, dan koma | "_Spasi di depan, dan koma" |
"kutipan awal, koma | """kutipan awal, koma" |
_spasi, koma baris kedua, dan tanda kutip ganda" |
"_spasi, koma baris kedua, dan tanda kutip ganda""" |
Cara termudah untuk menangani semua kondisi ini adalah dengan menulis metode sanitasi. Data yang dipertanyakan masuk, dan nilai CSV yang bagus dan bersih akan keluar. Berikut ini contoh implementasi yang baik dari metode tersebut.
private String sanitizeForCsv(String cellData) { StringBuilder resultBuilder = new StringBuilder(cellData); // Look for doublequotes, escape as necessary. int lastIndex = 0; while (resultBuilder.indexOf("\"", lastIndex) >= 0) { int quoteIndex = resultBuilder.indexOf("\"", lastIndex); resultBuilder.replace(quoteIndex, quoteIndex + 1, "\"\""); lastIndex = quoteIndex + 2; } char firstChar = cellData.charAt(0); char lastChar = cellData.charAt(cellData.length() - 1); if (cellData.contains(",") || // Check for commas cellData.contains("\n") || // Check for line breaks Character.isWhitespace(firstChar) || // Check for leading whitespace. Character.isWhitespace(lastChar)) { // Check for trailing whitespace resultBuilder.insert(0, "\"").append("\""); // Wrap in doublequotes. } return resultBuilder.toString(); }
Metode dimulai dengan memeriksa tanda kutip ganda yang ada. Hal ini harus dilakukan sebelum semua pemeriksaan lainnya, karena melibatkan penggabungan string dengan tanda kutip ganda, dan akan mengganggu jika menentukan perbedaan antara tanda kutip ganda yang merupakan bagian dari nilai dan tanda kutip ganda yang ditambahkan sebelumnya oleh metode ini. Ini mudah dihindari—mereka hanya perlu diperbesar dua kali. Setiap " menjadi "", setiap "" menjadi """", dan seterusnya.
Setelah kondisi tersebut terpenuhi, semua kondisi lainnya (spasi kosong, koma, dan baris baru) dapat diperiksa. Jika ada, cukup kurung nilai dalam tanda kutip ganda.
Perlu diketahui bahwa cara di atas menggunakan objek StringBuilder
, jangan pernah memanipulasi string mentah secara langsung. Hal ini karena
StringBuilder
memungkinkan Anda memanipulasi string dengan bebas tanpa membuat
salinan sementara di memori. Karena string di Java tidak dapat diubah, setiap penyesuaian
kecil yang Anda buat akan membuat string baru. Ketika menelusuri data {i>spreadsheet<i},
data ini akan bertambah dengan cepat.
Jumlah baris | x Nilai per baris | x Perubahan nilai | = Total String Baru yang Dibuat |
---|---|---|---|
10.000 | 10 | 3 | 300.000 |
Apa Selanjutnya?
Karena sekarang Anda diberi palu emas, mencari paku adalah hal yang wajar. Berikut ini beberapa ide untuk membantu Anda memulai.
- Lihat contoh kode sumber aplikasi yang menggunakan class ini untuk mencetak file CSV berdasarkan kueri contoh. Fungsi ini mengambil nama file output sebagai parameter command line, dan mencetaknya ke output standar secara default. Gunakan sebagai titik awal, buat sesuatu yang luar biasa!
- CSV hanyalah salah satu dari banyak format yang populer. Sesuaikan class untuk menghasilkan output ke format yang berbeda, seperti TSV, YAML, JSON, atau XML.
- Tulis aplikasi yang membuat CSV dan mengirimkannya melalui email jika sudah selesai. Pelaporan bulanan otomatis yang mudah.
- Tulis aplikasi yang memungkinkan Anda memasukkan kueri secara interaktif, sebagai antarmuka yang andal untuk menggali data lebih dalam.