複数の予定をカレンダーに一括登録する方法
やりたいこと
Excel 等で作成した予定を、一括でAppleのカレンダーアプリに登録する方法をググってみたら、CSV 形式のものを一度 Google カレンダーに 一括インポートして、それをエクスポートしたものをAppleカレンダーに読み込ませるとあった。
そこで、1行目に項目識別のキーワードを入れた次のような表を作って CSV に書き出した。
これをCSV形式で保存すると、こんな感じになります。
Subject,Start Date,Start Time,End Date,End Time
出勤,2023/2/10,9:00,2023/2/10,15:00
出勤,2023/2/11,10:00,2023/2/1,16:00
出勤,2023/2/12,9:00,2023/2/12,15:00
ところがGoogle カレンダーへのインポートできず!
ググった記事には CSV 形式でインポートできるとあったが、できなくなったみたい。iCal または VCS形式ならインポートできると書いてあった! (それ以外は受け付けない)
CSV を iCal に変換しよう!
せっかく作った CSV データを iCal 形式に変換する方法を探してみたら、次のサイトがありました。
https://csv-to-ical.chimbori.com/
早速試してみると、ちゃんと Appleカレンダー、Googleカレンダーのどちらにも一括登録できるデータが出来上がりました。
プログラマの血が騒いで、自分で作ってみた
上記の手順で、当初の目的は果たせましたが、プログラマの血が騒いで、変換プログラムを作ってみたくなった。(笑)
JavaScript に CSV 形式をパースするライブラリもありますが、データの配列順を変えない前提で、通常のテキストとして単純に処理するようにしました。(1行目のデータは無視(笑))
ということで、 GUI をHTMLで、 処理の部分をJavaScript で行うやり方で、単一ファイルの Webアプリとしました。
<!doctype html>
<html>
<head>
<meta charset="utf-8"></meta>
<title>CSV to iCalコンバータ</title>
</head>
<body>
<h3>CSV to iCal コンバータ</h3>
<div>
<h3>変換前</h3>
<form name="inputForm">
<input name="inFile" type="file" /><br />
<textarea name="inData" cols="80" rows="10"></textarea>
</form>
<h3>変換後</h3>
<form name="outForm">
<textarea name="outData" cols="80" rows="20"></textarea>
<a id="btn" download="iCal.ics">ダウンロード</a>
</form>
</div>
<script type="module">
var form = document.forms.inputForm;
form.inFile.addEventListener( 'change', function(e) {
const result = e.target.files[0];
const reader = new FileReader();
reader.readAsText( result );
reader.addEventListener( 'load', function() {
form.inData.textContent = reader.result;
document.forms.outForm.outData.textContent = conv(reader.result.split("\r")); // 改行コードに注意
})
})
var conv = function(csv) {
let iCal = "BEGIN:VCALENDAR\r";
iCal += "VERSION:2.0\r";
iCal += "CALSCALE:GREGORIAN\r";
iCal += "X-WR-CALNAME;VALUE=TEXT:iCal\r";
for (let i = 1; i < csv.length; ++i) { // 1行目を無視
let cells = csv[i].split(",");
if (cells.length != 1) {
let event = makeEvent(cells);
iCal += event;
}
}
iCal = iCal + "END:VCALENDAR\r";
return iCal;
}
var makeEvent = function(cells) {
let ev = "BEGIN:VEVENT\r";
ev += "SUMMARY:" + cells[0] + "\r";
ev += "DTSTAMP:" + dateConv(cells[1]) + "T" + timeConv(cells[2]) + "\r";
ev += "DTSTART:" + dateConv(cells[1]) + "T" + timeConv(cells[2]) + "\r";
ev += "DTEND:" + dateConv(cells[3]) + "T" + timeConv(cells[4]) + "\r";
ev += "END:VEVENT\r";
return ev;
}
var dateConv = function(dateIn) {
const dw = dateIn.split("/");
return dw[0] + ("0" + dw[1]).substr(-2) + ("0" + dw[2]).substr(-2)
}
var timeConv = function(timeIn) {
const tw = timeIn.split(":");
return ("0" + tw[0]).substr(-2) + ("0" + tw[1]).substr(-2) + "00";
}
</script>
<script type="module">
const btn = document.getElementById('btn');
console.log("btn");
btn.addEventListener('click', function() {
const blob = new Blob([document.forms.outForm.outData.textContent], {"type": "text/plain"});
btn.href = window.URL.createObjectURL(blob);
})
</script>
</body>
</html>
使い方
上記のソースをHTML拡張子を付けて保存し、そのファイルを Web ブラウザーで開いて、「ファイルを選択」で csv 形式のデータを開くと、すぐに iCal データに変換します。あとは「ダウンロード」すれば、テキストファイルとして保存されます。
使用上の注意
macOS で動作していますが、Windows だと、文字コード、改行コードが違って正常に動作しないかもしれません。その際は適当に JavaScript を修正してお使いください。
また、冒頭で書いているようにデータの並びに依存していますので、それに合わせてください。