Joplin批量导入Markdown文件完整教程:Obsidian/Blog/Notion迁移指南

立即下载Joplin 中文下载站 全平台支持 · 官方最新版

为什么要批量导入Markdown到Joplin

很多用户想从其他笔记工具迁移到Joplin,手头可能已有大量Markdown文件:

Joplin原生支持以下三种导入方式:

来源 Joplin支持 难度
本地Markdown文件 / 文件夹 ✓(官方支持) 低
ZIP压缩包(里面md+附件) ✓(官方支持) 低
ENEX(Evernote导出) ✓ 低
ENML(Evernote格式) ✓ 低
单个 .md 文件 ✓ 极低
JEX(Joplin专用导出) ✓ 极低
Markdown批量带Frontmatter ⚠️部分支持 中
Obsidian链接语法 [[]] ❌不转换 需手动/插件

本文按“批量迁移”场景,详解如何高效导入不同来源的Markdown文件到Joplin。

方法一:导入文件夹(最常用)

操作步骤

  1. Joplin主界面:文件 → 导入 → MD files (directories)
  2. 选择你的Markdown文件所在的文件夹根目录
  3. Joplin会递归扫描所有.md文件并导入

导入行为详解

文件特征 Joplin处理
文件名为 *.md 导入为独立笔记
文件包含YAML Frontmatter 自动解析,识别为笔记元数据(注意:Joplin对Frontmatter字段支持有限)
文件夹结构 不会自动创建对应笔记本结构(全部丢到根目录)
图片引用 ![](image.png) 自动复制image.png到Joplin资源库,链接重写

重要提醒

⚠️ 导入不会保留目录层级。如果你有/Posts/2026/post1.md,导入后所有笔记都挤在一个默认笔记本下。

解决方法:见下文“方法四:用脚本批量分配到笔记本”。

方法二:导入ZIP压缩包

适合“整库迁移”场景。

适用情况

操作步骤

  1. Joplin → 文件 → 导入 → MD files (zip)
  2. 选择zip压缩包
  3. 等待解压并导入

ZIP结构建议

Joplin能识别zip里的md文件,但对子目录嵌套的处理规则是:

Notes.zip
├── note1.md  ✓ 导入
├── note2.md  ✓ 导入
├── folder1/
│   ├── note3.md  ✓ 导入 (folder1会被忽略)
│   └── image.png  ✓ 作为资源
└── folder2/subfolder/note4.md  ✓ 导入

所有md笔记平铺到当前笔记本,文件夹结构不保留。

方法三:从Notion导入

Notion导出Markdown是常见需求。

Notion导出步骤

  1. 在Notion页面:... → Export
  2. 格式选Markdown & CSV
  3. 选项:Include subpages ✓、Create folder for each subpage ✓
  4. 下载zip

Joplin导入步骤

  1. Joplin → 文件 → 导入 → MD files (zip)
  2. 选Notion导出的zip
  3. Joplin会批量导入所有md文件

特殊处理

Notion特性 Joplin导入效果
嵌套页面 平铺到默认笔记本
数据库视图 转为静态表格
图片/文件附件 自动复制到资源库
Notion公式 ❌丢失
同步块 ❌丢失
@mentions 转为普通文本
日期/选择属性 ❌不会同步

Notion迁移到Joplin,内容会有损失,这是必须接受的取舍。

方法四:从Obsidian导入

Obsidian是Joplin的主要“对手”(都主打本地Markdown)。从Obsidian迁移到Joplin需要注意:

Obsidian的特殊性

批量迁移方案

步骤1:导出Obsidian Vault到zip

  1. Obsidian → 设置 → 第三方插件 → 搜索“Zipper”安装
  2. 或手动zip整个Vault文件夹(排除.obsidian/配置目录)

步骤2:Joplin导入zip

Joplin → 文件 → 导入 → MD files (zip)

步骤3:处理Obsidian的[[双链]]

Obsidian的双链在Joplin里会显示为纯文本“[[双链]]“,无法点击跳转。可以批量处理:

# 用Python脚本预处理Obsidian的md文件
import re
import os
import pathlib

def convert_obsidian_links(input_dir, output_dir):
    """把 [[Note Name]] 转为 [Note Name](#note-name)"""
    for md_file in pathlib.Path(input_dir).rglob('*.md'):
        content = md_file.read_text(encoding='utf-8')
        # [[Note Name]] -> [Note Name](#note-name)
        def repl(m):
            name = m.group(1)
            anchor = name.lower().replace(' ', '-')
            return f'[{name}](#{anchor})'
        new_content = re.sub(r'\[\[([^\]]+)\]\]', repl, content)
        output_path = pathlib.Path(output_dir) / md_file.relative_to(input_dir)
        output_path.parent.mkdir(parents=True, exist_ok=True)
        output_path.write_text(new_content, encoding='utf-8')

# 运行
convert_obsidian_links('./ObsidianVault', './JoplinImport')

然后把处理后的文件夹导入Joplin。

方法五:从Blog/Hexo/Hugo导入

如果你是博主,想把以前的博客文章搬到Joplin做归档:

Hexo博客导入

Hexo博客的md文件长这样:

---
title: 旧博客标题
date: 2025-03-15 14:30
tags:
  - 技术
  - JavaScript
---
正文内容...

Joplin导入时会丢失自定义Frontmatter字段(tags、categories等)。可以用脚本预处理。

Hugo博客导入

Hugo博客的Frontmatter是TOML或YAML:

+++
title = "Hugo文章"
date = 2025-04-01T00:00:00Z
draft = false
+++

Toml格式Frontmatter Joplin完全识别不了,必须先用工具转YAML或纯md。

批量预处理脚本

# Python脚本:把Obsidian/Hexo/Hugo的md文件转为Joplin能导入的格式
import re
from pathlib import Path
import frontmatter

def preprocess_for_joplin(md_file):
    try:
        post = frontmatter.load(md_file)
        # 提取关键字段转为Joplin支持的属性
        title = post.get('title', md_file.stem)
        tags = post.get('tags', [])
        if isinstance(tags, str):
            tags = [t.strip() for t in tags.split(',')]
        
        # 创建Joplin格式
        md_body = post.content
        # Hexo特殊语法 {{< xxx >}}
        md_body = re.sub(r'{{< [^>]+ >}}', '', md_body)
        # Obsidian特有块 ```block
        md_body = re.sub(r'```block', '```', md_body)
        
        # 输出标准Frontmatter,Joplin能识别title/tags
        output = f'---\ntitle: "{title}"\n'
        if tags:
            output += f'tags: [{", ".join(tags)}]\n'
        output += f'---\n\n{md_body}'
        
        return output
    except Exception as e:
        return md_file.read_text(encoding='utf-8')

# 批量处理
for md_file in Path('./source/_posts').glob('*.md'):
    new_content = preprocess_for_joplin(md_file)
    output_path = Path('./joplin_import') / md_file.name
    output_path.write_text(new_content, encoding='utf-8')

方法六:保留文件夹结构(进阶)

如果你希望Joplin里的笔记本结构与源文件夹一致,需要:

步骤1:安装node脚手架

Joplin自带CLI:

# 安装Joplin命令行工具
sudo npm install -g joplin

# 配置
joplin config sync.target 0  # 关闭同步,纯本地
joplin config appdir ~/JoplinData

步骤2:编写批量导入脚本

// import-folders.js
const joplin = require('joplin');
const fs = require('fs');
const path = require('path');

async function main() {
    await joplin.connect();
    
    const sourceDir = '/path/to/MarkdownFiles';
    
    async function importFolder(dir, parentId) {
        const entries = fs.readdirSync(dir, { withFileTypes: true });
        
        for (const entry of entries) {
            const fullPath = path.join(dir, entry.name);
            
            if (entry.isDirectory()) {
                // 创建子笔记本(递归)
                const notebook = await joplin.notebooks.create({
                    title: entry.name,
                    parent_id: parentId
                });
                await importFolder(fullPath, notebook.id);
            } else if (entry.name.endsWith('.md')) {
                // 导入md文件
                const content = fs.readFileSync(fullPath, 'utf-8');
                await joplin.notes.create({
                    title: path.parse(entry.name).name,
                    body: content,
                    parent_id: parentId
                });
                console.log(`导入: ${entry.name}`);
            }
        }
    }
    
    await importFolder(sourceDir, '');
    console.log('完成!');
}

main().catch(console.error);

步骤3:运行脚本

node import-folders.js

这样导入后,Joplin的笔记本结构与源文件夹完全对应。

保留附件和图片

Joplin对附件的处理

导入Markdown时,Joplin自动检测引用的本地图片:

Markdown图片引用 Joplin导入行为
![](image.png) image.png复制到资源库
![](../../assets/x.png) 复制并重写相对路径
<img src="x.png"> 部分识别
远程图片 ![](https://...) 不下载,保留链接
base64内嵌图片 ⚠️部分版本支持

注意事项

  1. 先整理好图片路径:把md文件和图片放在同一目录或子目录
  2. 避免中文文件名:某些版本对中文路径处理异常
  3. 大文件(>100MB)导入慢:Joplin处理大图片时会重新索引

常见问题排查

问题1:导入后中文标题变成乱码

# 解决方案:导入前确认md文件编码为UTF-8
# 检查方法
file -i note.md
# 输出应为: text/plain; charset=utf-8

# 如果不是,转换编码
iconv -f GBK -t UTF-8 old.md > new.md

问题2:Frontmatter显示为正文

如果原本的Frontmatter被当作正文显示,可能是:

  1. --- 前后有空行不一致
  2. YAML格式错误
  3. 文件不是.md扩展名
正确的Frontmatter:

---
title: 文章标题
---

正文开始

问题3:导入后没有自动转换为笔记

确保:

  1. 文件确实以.md结尾
  2. 不是.markdown或.txt等其他扩展名
  3. 文件非空

问题4:导入很慢,卡在某个文件

通常是大文件(几百MB)或损坏文件。建议:

  1. 分批导入
  2. 检查文件:file broken.md、hexdump -C broken.md | head
  3. 用备份文件替代

问题5:导入后图片不显示

1. 检查图片文件是否被复制到Joplin资源库
2. 检查note的源Markdown引用路径
3. 有时需要手动重新上传图片

Joplin的资源库查看:设置 → Note → Resources

问题6:导入的笔记没有创建时间

如果原md文件有created: 2024-01-01,Joplin不会识别该字段。可以用Joplin API批量修复:

joplin --profile set-by-api \
  --note <NOTE_ID> \
  --created-time 2024-01-01T00:00:00Z

总结:批量导入Markdown的关键决策

来源 推荐方法 注意事项
单个md文件 Joplin拖入或导入 → MD 最简单
多md文件夹 导入 → MD files (directories) 不保留目录
整库zip 导入 → MD files (zip) 不保留目录
Obsidian Vault zip导入 + 预处理脚本 处理[[双链]]
Notion zip导入 损失较多功能
Hexo/Hugo 脚本预处理Frontmatter 转YAML标准格式
复杂目录结构 node脚本批量导入 保留笔记本层级

最重要的两个最佳实践:

  1. 批量导入前先做一个小测试(比如5-10个文件),验证效果满意再大量导入
  2. 导入前备份原始文件,万一效果不理想可以无损撤回

如果你正打算从其他笔记工具迁移到Joplin,这些方法应该能帮你平滑过渡。但要记住:Joplin不是100%兼容Obsidian或Notion的所有特性,迁移总有取舍,关键是看你的核心需求是什么。

这篇教程有帮助吗?立即下载Joplin 中文下载站试试吧!

全平台支持 · 安全无毒 · 官方最新版