やりたかったこと
Excel 等で作成した予定を、一括でAppleのカレンダーアプリに登録したかった。
ググると、一度 Google カレンダーに CSV 形式のものを一括インポートして、それをエクスポートしたものをAppleカレンダーに読み込ませるとあった。
そのためには1行目に項目識別のキーワードを入れた次のような表を作って CSV に書き出した。
■ 表データ(Excelなどで)
Subject | Start Date | Start Time | End Date | End Time |
---|---|---|---|---|
出勤 | 2023/2/10 | 9:00 | 2023/2/10 | 15:00 |
出勤 | 2023/2/11 | 9:00 | 2023/2/11 | 15:00 |
出勤 | 2023/2/12 | 9:00 | 2023/2/12 | 15:00 |
■ csvデータ
Subject,Start Date,Start Time,End Date,End Time
出勤,2023/2/10,9:00,2023/2/10,15:00
出勤,2023/2/11,9:00,2023/2/1,15: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行目のデータは無視(笑))
ということで、HTMLで GUI を、 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 の68行目を修正してお使いください。
また、冒頭で書いているようにデータの並びに依存していますので、それに合わせてください。