使用CloudFlare Markdown转换从Excel中提取大学学期日期
高级
这是一个AI领域的自动化工作流,包含 18 个节点。主要使用 Set, Code, Sort, Gmail, SplitOut 等节点,结合人工智能技术实现智能自动化。 使用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": "当点击\"测试工作流\"时",
"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 聊天模型",
"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. 使用Cloudflare®️ Markdown转换解析Excel文件"
},
"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. 使用AI将学期日期提取为事件"
},
"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. 使用事件创建ICS文档"
},
"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. 创建用于导入的ICS二进制文件"
},
"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账户"
},
"typeVersion": 1
},
{
"id": "6a2d8e78-0b15-498f-bc96-bbbac1da1f21",
"name": "便签说明5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1020,
-880
],
"parameters": {
"width": 420,
"height": 1380,
"content": "## 试试看!"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"Fix Dates": {
"main": [
[
{
"node": "Sort Events by Date",
"type": "main",
"index": 0
}
]
]
},
"Create ICS File": {
"main": [
[
{
"node": "Send Email with Attachment",
"type": "main",
"index": 0
}
]
]
},
"Events to Items": {
"main": [
[
{
"node": "Fix Dates",
"type": "main",
"index": 0
}
]
]
},
"Sort Events by Date": {
"main": [
[
{
"node": "Events to ICS Document",
"type": "main",
"index": 0
}
]
]
},
"Extract Target Sheet": {
"main": [
[
{
"node": "Extract Key Events and Dates",
"type": "main",
"index": 0
}
]
]
},
"Get Term Dates Excel": {
"main": [
[
{
"node": "Markdown Conversion Service",
"type": "main",
"index": 0
}
]
]
},
"Events to ICS Document": {
"main": [
[
{
"node": "Create ICS File",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Extract Key Events and Dates",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Markdown Conversion Service": {
"main": [
[
{
"node": "Extract Target Sheet",
"type": "main",
"index": 0
}
]
]
},
"Extract Key Events and Dates": {
"main": [
[
{
"node": "Events to Items",
"type": "main",
"index": 0
}
]
]
},
"When clicking ‘Test workflow’": {
"main": [
[
{
"node": "Get Term Dates Excel",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 人工智能
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
在可视化参考库中探索n8n节点
在可视化参考库中探索n8n节点
If
Ftp
Set
+93
113 节点I versus AI
其他
YouTube RAG 搜索前端(使用 Apify、Qdrant 和 AI)
基于 Apify、Qdrant 和 AI 的 YouTube RAG 搜索前端
If
Set
Html
+23
62 节点Jimleuk
人工智能
使用AI自动化品牌风格博客创建
使用AI自动化品牌风格博客创建
Set
Html
Limit
+11
27 节点Jimleuk
人工智能
使用AI和APIFY自动化销售会议准备并发送至WhatsApp
使用AI和APIFY自动化销售会议准备并发送至WhatsApp
If
Set
Html
+15
61 节点Jimleuk
销售
构建基于n8n和Gemini AI图像编辑的图像修复服务
构建基于n8n和Gemini AI图像编辑的图像修复服务
Set
Split Out
Google Drive
+5
17 节点Jimleuk
设计
构建自定义Qdrant向量存储MCP服务器
构建自定义Qdrant向量存储MCP服务器
If
Set
Code
+14
44 节点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 查看 →
分享此工作流