GoogleカレンダーからエクスポートするとiCalendarファイル(iCal形式)というテキストデータになります。
例えば、千葉ロッテの今年の日程をエクスポートすると次のようになります。
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:CLM2014
X-WR-TIMEZONE:Asia/Tokyo
X-WR-CALDESC:千葉ロッテマリーンズ2014年日程
BEGIN:VEVENT
DTSTART:20140814T090000Z
DTEND:20140814T120000Z
DTSTAMP:20140224T001600Z
UID:CSVConvertxxx
CREATED:19000101T120000Z
DESCRIPTION:
LAST-MODIFIED:20140125T123028Z
LOCATION:札幌ドーム
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:北海道日本ハム
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:CLM2014
X-WR-TIMEZONE:Asia/Tokyo
X-WR-CALDESC:千葉ロッテマリーンズ2014年日程
BEGIN:VEVENT
DTSTART:20140814T090000Z
DTEND:20140814T120000Z
DTSTAMP:20140224T001600Z
UID:CSVConvertxxx
CREATED:19000101T120000Z
DESCRIPTION:
LAST-MODIFIED:20140125T123028Z
LOCATION:札幌ドーム
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:北海道日本ハム
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
見やすいようにインデントを施すと次のようになります。
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:CLM2014
X-WR-TIMEZONE:Asia/Tokyo
X-WR-CALDESC:千葉ロッテマリーンズ2014年日程
BEGIN:VEVENT
DTSTART:20140814T090000Z
DTEND:20140814T120000Z
DTSTAMP:20140224T001600Z
UID:CSVConvertxxx
CREATED:19000101T120000Z
DESCRIPTION:
LAST-MODIFIED:20140125T123028Z
LOCATION:札幌ドーム
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:北海道日本ハム
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:CLM2014
X-WR-TIMEZONE:Asia/Tokyo
X-WR-CALDESC:千葉ロッテマリーンズ2014年日程
BEGIN:VEVENT
DTSTART:20140814T090000Z
DTEND:20140814T120000Z
DTSTAMP:20140224T001600Z
UID:CSVConvertxxx
CREATED:19000101T120000Z
DESCRIPTION:
LAST-MODIFIED:20140125T123028Z
LOCATION:札幌ドーム
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:北海道日本ハム
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
実際には「BEGIN:VEVENT~END:VEVENT」が繰り返されます。ここがデータの本体と言えます。
この形式はXMLに似ています。試しに書きなおしてみると次のようになります。
<?xml version="1.0" encoding="UTF-8" ?>
<VCALENDAR>
<PRODID>-//Google Inc//Google Calendar 70.9054//EN</PRODID>
<VERSION>2.0</VERSION>
<CALSCALE>GREGORIAN</CALSCALE>
<METHOD>PUBLISH</METHOD>
<X-WR-CALNAME>CLM2014</X-WR-CALNAME>
<X-WR-TIMEZONE>Asia/Tokyo</X-WR-TIMEZONE>
<X-WR-CALDESC>千葉ロッテマリーンズ2014年日程</X-WR-CALDESC>
<VEVENT>
<DTSTART>20140814T090000Z</DTSTART>
<DTEND>20140814T120000Z</DTEND>
<DTSTAMP>20140224T001600Z</DTSTAMP>
<UID>CSVConvertxxx</UID>
<CREATED>19000101T120000Z</CREATED>
<DESCRIPTION></DESCRIPTION>
<LAST-MODIFIED>20140125T123028Z</LAST-MODIFIED>
<LOCATION>札幌ドーム</LOCATION>
<SEQUENCE>0</SEQUENCE>
<STATUS>CONFIRMED</STATUS>
<SUMMARY>北海道日本ハム</SUMMARY>
<TRANSP>OPAQUE</TRANSP>
</VEVENT>
</VCALENDAR>
<VCALENDAR>
<PRODID>-//Google Inc//Google Calendar 70.9054//EN</PRODID>
<VERSION>2.0</VERSION>
<CALSCALE>GREGORIAN</CALSCALE>
<METHOD>PUBLISH</METHOD>
<X-WR-CALNAME>CLM2014</X-WR-CALNAME>
<X-WR-TIMEZONE>Asia/Tokyo</X-WR-TIMEZONE>
<X-WR-CALDESC>千葉ロッテマリーンズ2014年日程</X-WR-CALDESC>
<VEVENT>
<DTSTART>20140814T090000Z</DTSTART>
<DTEND>20140814T120000Z</DTEND>
<DTSTAMP>20140224T001600Z</DTSTAMP>
<UID>CSVConvertxxx</UID>
<CREATED>19000101T120000Z</CREATED>
<DESCRIPTION></DESCRIPTION>
<LAST-MODIFIED>20140125T123028Z</LAST-MODIFIED>
<LOCATION>札幌ドーム</LOCATION>
<SEQUENCE>0</SEQUENCE>
<STATUS>CONFIRMED</STATUS>
<SUMMARY>北海道日本ハム</SUMMARY>
<TRANSP>OPAQUE</TRANSP>
</VEVENT>
</VCALENDAR>
ここからが本題です。
iCalendarファイルをExcelに読み込ませる方法を考えます。直接は無理なので一度、TSV(タブ付き区切り)に変換します。TSVならばExcelにインポートさせられます。
JavaScriptを使います。
上で見たように「BEGIN:VEVENT~END:VEVENT」の部分だけを取り出します。
function ical2tsv(list) {
var events, lines, records, parts, tags, results, cells;
var i, j, events_length, lines_length, tags_length;
//整形
list = list.replace(/\r/g, "");
list = list.replace(/\n /g, "");
//取得
events = list.match(/BEGIN:VEVENT[\s\S]*?END:VEVENT/g);
events_length = events.length;
records = [];
tags = [];
for (i = 0; i < events_length; i++) {
records[i] = [];
lines = events[i].match(/.*:.*/g);
lines_length = lines.length;
for (j = 0; j < lines_length; j++) {
parts = lines[j].match(/(.*?):(.*)/);
records[i][parts[1]] = parts[2];
tags.push(parts[1]);
}
}
tags = unique(tags);
//TSV
results = [];
results.push(tags.join("\t"));
tags_length = tags.length;
for (i = 0; i < events_length; i++) {
cells = [];
for (j = 0; j < tags_length; j++) {
cells[j] = records[i][tags[j]];
}
results.push(cells.join("\t"));
}
return results.join("\n");
}
var events, lines, records, parts, tags, results, cells;
var i, j, events_length, lines_length, tags_length;
//整形
list = list.replace(/\r/g, "");
list = list.replace(/\n /g, "");
//取得
events = list.match(/BEGIN:VEVENT[\s\S]*?END:VEVENT/g);
events_length = events.length;
records = [];
tags = [];
for (i = 0; i < events_length; i++) {
records[i] = [];
lines = events[i].match(/.*:.*/g);
lines_length = lines.length;
for (j = 0; j < lines_length; j++) {
parts = lines[j].match(/(.*?):(.*)/);
records[i][parts[1]] = parts[2];
tags.push(parts[1]);
}
}
tags = unique(tags);
//TSV
results = [];
results.push(tags.join("\t"));
tags_length = tags.length;
for (i = 0; i < events_length; i++) {
cells = [];
for (j = 0; j < tags_length; j++) {
cells[j] = records[i][tags[j]];
}
results.push(cells.join("\t"));
}
return results.join("\n");
}
function unique(array) {
var array_length, unique_array, check, i;
array_length = array.length;
unique_array = [];
check = [];
for (i = 0; i < array_length; i++) {
if (!check[array[i]]) {
check[array[i]] = true;
unique_array.push(array[i]);
}
}
return unique_array;
}
var array_length, unique_array, check, i;
array_length = array.length;
unique_array = [];
check = [];
for (i = 0; i < array_length; i++) {
if (!check[array[i]]) {
check[array[i]] = true;
unique_array.push(array[i]);
}
}
return unique_array;
}
iCalendarファイルは「DTSTART」などのタグ(見出しに相当)が全てのレコードで共通でないケースがあります。
そこで、一度、すべてのタグを抽出し、重複がないように整理して、並べています。
「list = list.replace(/\n /g, “”)」の部分が奇妙な感じです。iCalendarファイルは長いテキスト(「DESCRIPTION」)については半角100字ごとに「改行+半角スペース」が挿入されます。これを削除しています。
「ical2tsv」については次のページで試すことができます。
コメント
[…] なお「unique」という自作の関数を使っています。「GoogleカレンダーからExcelにデータを移行する方法」に書かれています。 […]