Excelから大学の学期日付を抽出し、CloudFlare Markdown変換を使う
上級
これはAI分野の自動化ワークフローで、18個のノードを含みます。主にSet, Code, Sort, Gmail, SplitOutなどのノードを使用、AI技術を活用したスマート自動化を実現。 CloudFlare Markdown変換を使用してExcelから大学の学期日付を抽出
前提条件
- •Googleアカウント + Gmail API認証情報
- •ターゲットAPIの認証情報が必要な場合あり
- •Google Gemini API Key
使用ノード (18)
カテゴリー
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
"meta": {
"instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "dbaac3bd-6049-4f2e-8782-98b1656d8331",
"name": "「Test workflow」をクリックした時",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-500,
-20
],
"parameters": {},
"typeVersion": 1
},
{
"id": "6605c1b6-4723-4aeb-9ade-ac05350e7631",
"name": "学期日程Excelを取得",
"type": "n8n-nodes-base.httpRequest",
"position": [
-140,
0
],
"parameters": {
"url": "https://www.westminster.ac.uk/sites/default/public-files/general-documents/undergraduate-term-dates-2025%E2%80%932026.xlsx",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"typeVersion": 4.2
},
{
"id": "ed83ae3c-ebf7-42b5-9317-4e1fbd88905c",
"name": "主要イベントと日程を抽出",
"type": "@n8n/n8n-nodes-langchain.informationExtractor",
"position": [
640,
-20
],
"parameters": {
"text": "={{ $json.target_sheet }}",
"options": {
"systemPromptTemplate": "Capture the values as seen. Do not convert dates."
},
"schemaType": "manual",
"inputSchema": "{\n\t\"type\": \"array\",\n\t\"items\": {\n\t \"type\": \"object\",\n \"properties\": {\n \"week_number\": { \"type\": \"number\" },\n \"week_beginning\": { \"type\": \"string\" },\n \"title\": { \"type\": \"string\" }\n }\n\t}\n}"
},
"typeVersion": 1
},
{
"id": "78af1a09-6aa7-48f9-af2a-539a739c6571",
"name": "対象シートを抽出",
"type": "n8n-nodes-base.set",
"position": [
300,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "0dd68450-2492-490a-ade1-62311eb541ef",
"name": "target_sheet",
"type": "string",
"value": "={{ $json.result[0].data.split('##')[9] }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "4bec1392-c262-4256-8199-54c101f281c2",
"name": "日程を修正",
"type": "n8n-nodes-base.set",
"position": [
1320,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c6f0fa0e-1cbf-4da9-8928-a11502da0991",
"name": "week_beginning",
"type": "string",
"value": "={{\nnew Date(2025,8,15,0,0,0).toDateTime().toUTC()\n .plus({ 'day': $json.week_beginning - 45915 })\n}}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "0df44568-4bc6-46ed-9419-5462f528dbc3",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
740,
120
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.5-pro-preview-03-25"
},
"credentials": {
"googlePalmApi": {
"id": "dSxo6ns5wn658r8N",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "13aa069f-dc32-4a57-9a57-29264a09c80d",
"name": "ICSファイルを作成",
"type": "n8n-nodes-base.convertToFile",
"position": [
2100,
-20
],
"parameters": {
"options": {
"fileName": "={{ $('Get Term Dates Excel').first().binary.data.fileName }}.ics",
"mimeType": "text/calendar"
},
"operation": "toBinary",
"sourceProperty": "data"
},
"typeVersion": 1.1
},
{
"id": "6cf27afd-8f16-40c7-bbc3-bba7fcf76097",
"name": "イベントをICSドキュメントに変換",
"type": "n8n-nodes-base.code",
"position": [
1720,
0
],
"parameters": {
"language": "python",
"pythonCode": "from datetime import datetime, timedelta\nimport base64\n\nasync def json_array_to_ics_pyodide(json_array, prodid=\"-//My Application//EN\"):\n \"\"\"\n Converts a JSON array of calendar events to ICS file content in a Pyodide environment.\n\n Args:\n json_array: A list of dictionaries, where each dictionary represents an event\n and contains keys like \"week_number\", \"week_beginning\", and \"title\".\n It's expected that \"week_beginning\" is an ISO 8601 formatted\n date string.\n prodid: The product identifier string for the ICS file.\n\n Returns:\n A string containing the content of the ICS file.\n \"\"\"\n ical = [\"BEGIN:VCALENDAR\",\n \"VERSION:2.0\",\n f\"PRODID:{prodid}\"]\n\n for event_data in json_array:\n week_number = event_data.get(\"week_number\")\n week_beginning_str = event_data.get(\"week_beginning\")\n title = event_data.get(\"title\")\n\n if week_beginning_str and title:\n try:\n # Parse the week_beginning string to a datetime object\n week_beginning = datetime.fromisoformat(week_beginning_str.replace('Z', '+00:00'))\n\n # Calculate the end of the week (assuming events last for the whole week)\n week_ending = week_beginning + timedelta(days=7)\n\n uid = f\"week-{week_number}-{week_beginning.strftime('%Y%m%d')}@my-application\"\n dtstamp = datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')\n dtstart = week_beginning.strftime('%Y%m%d')\n dtend = week_ending.strftime('%Y%m%d')\n summary = title\n\n ical.extend([\n \"BEGIN:VEVENT\",\n f\"UID:{uid}\",\n f\"DTSTAMP:{dtstamp}\",\n f\"DTSTART;VALUE=DATE:{dtstart}\",\n f\"DTEND;VALUE=DATE:{dtend}\",\n f\"SUMMARY:{summary}\",\n \"END:VEVENT\"\n ])\n\n # You can add more properties here if your JSON data contains them,\n # for example:\n # if \"description\" in event_data:\n # ical.append(f\"DESCRIPTION:{event_data['description']}\")\n # if \"location\" in event_data:\n # ical.append(f\"LOCATION:{event_data['location']}\")\n\n except ValueError as e:\n print(f\"Error processing event with week_beginning '{week_beginning_str}': {e}\")\n continue # Skip to the next event if there's a parsing error\n\n ical.append(\"END:VCALENDAR\")\n return \"\\r\\n\".join(ical)\n\nics_content = await json_array_to_ics_pyodide([item.json for item in _input.all()])\nics_bytes = ics_content.encode('utf-8')\nbase64_bytes = base64.b64encode(ics_bytes)\nbase64_string = base64_bytes.decode('utf-8')\n\nreturn {\n \"data\": base64_string\n}"
},
"typeVersion": 2
},
{
"id": "e5c94c64-4262-4951-a772-75af431e578a",
"name": "日程でイベントをソート",
"type": "n8n-nodes-base.sort",
"position": [
1520,
0
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"fieldName": "week_beginning"
}
]
}
},
"typeVersion": 1
},
{
"id": "3bbe74bb-cd20-4116-9272-12be8ac54700",
"name": "付箋",
"type": "n8n-nodes-base.stickyNote",
"position": [
-260,
-240
],
"parameters": {
"color": 7,
"width": 780,
"height": 500,
"content": "## 1. Parse Excel Files Using Cloudflare®️ Markdown Conversion\n[Learn more about Cloudflare's Markdown Conversion Service](https://developers.cloudflare.com/workers-ai/markdown-conversion/)\n\nToday's LLMs cannot parse Excel files directly so the best we can do is to convert the spreadsheet into a format that they can, namely markdown. To do this, we can use Cloudflare's brand new document conversion service which was designed specifically for this task. The result is the sheet is transcribed as a markdown table.\n\nThe **Markdown Conversion Service** is currently free to use at time of writing but requires a Cloudflare account."
},
"typeVersion": 1
},
{
"id": "18fc9626-1c55-4893-8e72-06c48754ceb8",
"name": "Markdown変換サービス",
"type": "n8n-nodes-base.httpRequest",
"position": [
80,
0
],
"parameters": {
"url": "https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/tomarkdown",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "files",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
}
]
},
"nodeCredentialType": "cloudflareApi"
},
"credentials": {
"cloudflareApi": {
"id": "qOynkQdBH48ofOSS",
"name": "Cloudflare account"
}
},
"typeVersion": 4.2
},
{
"id": "5f71bc64-985c-43c4-bdfa-3cfda7e9c060",
"name": "付箋1",
"type": "n8n-nodes-base.stickyNote",
"position": [
540,
-240
],
"parameters": {
"color": 7,
"width": 680,
"height": 540,
"content": "## 2. Extract Term Dates to Events Using AI\n[Learn more about the Information Extractor](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.information-extractor)\n\nData entry is probably the number one reason as to why we need AI/LLMs. This time-consuming and menial task can be completed in seconds and with a high degree of accuracy. Here, we ask the AI to extract each event with the term dates to a list of events using structured output."
},
"typeVersion": 1
},
{
"id": "e9083886-81e3-483e-b959-12ce9005d862",
"name": "付箋2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1240,
-240
],
"parameters": {
"color": 7,
"width": 660,
"height": 480,
"content": "## 3. Use Events to Create ICS Document\n[Learn more about the code node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/)\n\nNow we have our events, let's create a calendar to put them in. Using the code now, we can construct a simple ICS document - this is the format which can be imported into iCal, Google Calendar and Outlook. For tasks like these, the Code node is best suited to handle custom transformations."
},
"typeVersion": 1
},
{
"id": "04a7c856-88b4-4daa-a56f-6e2741907e4c",
"name": "イベントを項目に変換",
"type": "n8n-nodes-base.splitOut",
"position": [
1000,
-20
],
"parameters": {
"options": {},
"fieldToSplitOut": "output"
},
"typeVersion": 1
},
{
"id": "cab455c9-b15d-440d-9f30-7afe1af23ea8",
"name": "付箋3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1920,
-240
],
"parameters": {
"color": 7,
"width": 720,
"height": 480,
"content": "## 4. Create ICS Binary File for Import\n[Learn more about the Convert to File node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.converttofile)\n\nFinally with our ICS document ready, we can use the \"Convert to File\" node to build an ICS binary file which can be shared with team members, classmates or even instructors."
},
"typeVersion": 1
},
{
"id": "c0861ef1-08f4-49e9-a700-a7224296cc72",
"name": "添付ファイル付きメールを送信",
"type": "n8n-nodes-base.gmail",
"position": [
2340,
-20
],
"webhookId": "835ef864-60c4-4b84-84ee-104ee10644eb",
"parameters": {
"sendTo": "jim@example.com",
"message": "=Hey,\n\nPlease find attached calendar for Undergraduate terms dates 2025/2026.\n\nThanks",
"options": {
"attachmentsUi": {
"attachmentsBinary": [
{}
]
}
},
"subject": "Undergraduate Terms Dates Calendar 2025/2026",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "Sf5Gfl9NiFTNXFWb",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "85c4d928-83c7-445a-8e9b-d9daef05ae1d",
"name": "付箋4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-20,
200
],
"parameters": {
"color": 5,
"width": 280,
"height": 80,
"content": "### Cloudflare Account Required\nAdd your Cloudflare {ACCOUNT_ID} to the URL"
},
"typeVersion": 1
},
{
"id": "6a2d8e78-0b15-498f-bc96-bbbac1da1f21",
"name": "付箋5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1020,
-880
],
"parameters": {
"width": 420,
"height": 1380,
"content": "## Try it out!\n### This n8n template imports an XLSX containing terms dates for a university, extracts the relevant events using AI and converts the events to an ICS file which can be imported into iCal, Google Calendar or Outlook.\n\nManually adding important term dates to your calendar by hand? Stop! Automate it with this simple AI/LLM-powered document understanding and extraction template. This cool use-case can be applied to many scenarios where Excel files are predominantly used.\n\n### How it works\n* The term dates excel file (xlsx) are imported into the workflow from the university's website using the http request node.\n* To parse the excel file, we use an external service - [Cloudflare's Markdown Conversion Service](https://developers.cloudflare.com/workers-ai/markdown-conversion/). This converts the excel's sheets into markdown tables which our LLM can read.\n* To extract the events and their dates from the markdown, we can use the Information Extractor node for structured output. LLMs are great for this use-case because they can understand the layout; one row may have many data points.\n* With our data, there are endless possibilities to use it! But for this demonstration, we'll generate an ICS file so that we can import the extracted events into our calendar. We use the Python code node to combine the events into the ICS spec and the \"Convert to File\" node to create the ICS binary.\n* Finally, let's distribute the ICS file by email to other students or instructors who may also find this incredibly helpful for the upcoming semester!\n\n### How to use\n* Ensure you're downloading the correct excel file and amend the URL parameter of the \"Get Term Dates Excel\" as necessary.\n* Update the gmail node with your email or other emails as required. Alternatively, send the ICS file to Google Drive or a student portal.\n\n### Requirements\n* Cloudflare Account is required to use the Markdown Conversion Service.\n* Gemini for LLM document understanding and extraction.\n* Gmail for email sending.\n\n### Customising the workflow\n* This template should work for other Excel files which - for a university - there are many. Some will be more complicated than others so experiment with different parsers and extraction tools and strategies.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"4bec1392-c262-4256-8199-54c101f281c2": {
"main": [
[
{
"node": "e5c94c64-4262-4951-a772-75af431e578a",
"type": "main",
"index": 0
}
]
]
},
"13aa069f-dc32-4a57-9a57-29264a09c80d": {
"main": [
[
{
"node": "c0861ef1-08f4-49e9-a700-a7224296cc72",
"type": "main",
"index": 0
}
]
]
},
"04a7c856-88b4-4daa-a56f-6e2741907e4c": {
"main": [
[
{
"node": "4bec1392-c262-4256-8199-54c101f281c2",
"type": "main",
"index": 0
}
]
]
},
"e5c94c64-4262-4951-a772-75af431e578a": {
"main": [
[
{
"node": "6cf27afd-8f16-40c7-bbc3-bba7fcf76097",
"type": "main",
"index": 0
}
]
]
},
"78af1a09-6aa7-48f9-af2a-539a739c6571": {
"main": [
[
{
"node": "ed83ae3c-ebf7-42b5-9317-4e1fbd88905c",
"type": "main",
"index": 0
}
]
]
},
"6605c1b6-4723-4aeb-9ade-ac05350e7631": {
"main": [
[
{
"node": "18fc9626-1c55-4893-8e72-06c48754ceb8",
"type": "main",
"index": 0
}
]
]
},
"6cf27afd-8f16-40c7-bbc3-bba7fcf76097": {
"main": [
[
{
"node": "13aa069f-dc32-4a57-9a57-29264a09c80d",
"type": "main",
"index": 0
}
]
]
},
"0df44568-4bc6-46ed-9419-5462f528dbc3": {
"ai_languageModel": [
[
{
"node": "ed83ae3c-ebf7-42b5-9317-4e1fbd88905c",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"18fc9626-1c55-4893-8e72-06c48754ceb8": {
"main": [
[
{
"node": "78af1a09-6aa7-48f9-af2a-539a739c6571",
"type": "main",
"index": 0
}
]
]
},
"ed83ae3c-ebf7-42b5-9317-4e1fbd88905c": {
"main": [
[
{
"node": "04a7c856-88b4-4daa-a56f-6e2741907e4c",
"type": "main",
"index": 0
}
]
]
},
"dbaac3bd-6049-4f2e-8782-98b1656d8331": {
"main": [
[
{
"node": "6605c1b6-4723-4aeb-9ade-ac05350e7631",
"type": "main",
"index": 0
}
]
]
}
}
}よくある質問
このワークフローの使い方は?
上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。
このワークフローはどんな場面に適していますか?
上級 - 人工知能
有料ですか?
このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。
関連ワークフロー
n8nノードの探索(可視化リファレンスライブラリ内)
n8nノードを可視化リファレンスライブラリで探索
If
Ftp
Set
+
If
Ftp
Set
113 ノードI versus AI
その他
AIを使ったブランド文風のブログ作成の自動化
AIを使ってブランドスタイルのブログを自動生成
Set
Html
Limit
+
Set
Html
Limit
27 ノードJimleuk
人工知能
AIとAPIFYを使用して sales meeting の準備を自動化し、WhatsAppへ送信
AI と APIFY を使って営業会議の準備を自動化し WhatsApp へ送信
If
Set
Html
+
If
Set
Html
61 ノードJimleuk
営業
n8nとGemini AI画像編集を活用した画像修復サービスの構築
n8nとGemini AI画像編集による画像修復サービスの構築
Set
Split Out
Google Drive
+
Set
Split Out
Google Drive
17 ノードJimleuk
デザイン
カスタムQdrantベクタース토アMCPサーバーを構築
カスタムQdrantベクターストアMCPサーバーを構築する
If
Set
Code
+
If
Set
Code
44 ノードJimleuk
ビルディングブロック
n8n、Apify、OpenAI o3 を使用したセルフホスト型 AI ディープリサーチエージェント
n8n、Apify、OpenAI o3を使用したセルフホスト型AI深度リサーチエージェント
If
Set
Code
+
If
Set
Code
87 ノードJimleuk
人工知能
ワークフロー情報
難易度
上級
ノード数18
カテゴリー1
ノードタイプ11
作成者
Jimleuk
@jimleukFreelance consultant based in the UK specialising in AI-powered automations. I work with select clients tackling their most challenging projects. For business enquiries, send me an email at hello@jimle.uk LinkedIn: https://www.linkedin.com/in/jimleuk/ X/Twitter: https://x.com/jimle_uk
外部リンク
n8n.ioで表示 →
このワークフローを共有