这个你一定要知道,如何使用Pandoc创建HTML网页版文档?

在日常的工作和学习中,我们常常需要编写各类分析报告,并将其转换为 HTML 格式以便于分享和展示。比如做了一个系统平台,需要编写操作手册,可以通过 Pandoc 生成 HTML 网页文件,在平台添加相应的跳转就行。 Pandoc 作为一款强大的文档转换工具,能够轻松地将 Markdown 文件转换为 HTML 文档。本文将介绍如何使用 Pandoc 生成带左侧导航菜单的 HTML 分析报告,使页面布局更加合理美观,且点击导航菜单能够跳转到对应的内容,并为激活的菜单添加样式。下面是一个简单的案例,如果有类似需求结合自己的需求进行修改。

效果演示

一、Pandoc 的安装

pandoc.org/installing....

Windows 系统 :

可以从 Pandoc 官网下载 msi 安装程序,直接运行安装即可。安装过程中,安装程序会自动更新系统路径,将 Pandoc 二进制文件的目录添加到系统变量中。

也可以使用 Chocolatey 包管理工具安装,命令为 choco install pandoc。

MacOS 系统 :

使用 Homebrew 包管理工具,执行命令 brew install pandoc 即可完成安装。

Linux 系统 :

对于 Ubuntu/Debian 系统,使用命令 sudo apt install pandoc 进行安装;对于其他发行版,可使用对应包管理工具进行安装。

安装完成后,可以通过在终端或命令提示符中输入 pandoc --version 来验证 Pandoc 是否安装成功。若能显示 Pandoc 的版本信息,则说明安装正确。

项目结构

在开始前,我们先创建项目目录结构:

text 复制代码
report-project/
├── report.md          # Markdown报告内容
├── template.html      # HTML模板
└── output.html        # 生成的HTML报告

Markdown 报告文件(report.md)

markdown 复制代码
% 销售数据分析报告
% 数据分析团队
% 2023 年 10 月 15 日

## 报告概览 {#overview}

本报告分析了 2023 年第三季度的销售数据,涵盖销售额、区域表现、产品分类和客户行为等多个维度。

本报告分析了 2023 年第三季度的销售数据,涵盖销售额、区域表现、产品分类和客户行为等多个维度。

本报告分析了 2023 年第三季度的销售数据,涵盖销售额、区域表现、产品分类和客户行为等多个维度。

本报告分析了 2023 年第三季度的销售数据,涵盖销售额、区域表现、产品分类和客户行为等多个维度。

### 关键指标

**总销售额**: ¥1,842K

**同比增长**: 18.3%

**订单数量**: 23,584

**平均订单金额**: ¥78.10

### 可视化图表

<img src="https://pic1.zhimg.com/v2-bf964164ab3df51ede116972c655f524_r.jpg" alt="销售趋势" width="600">

## 销售趋势分析 {#sales-analysis}

第三季度销售额呈现稳定增长趋势,其中 9 月份销售额达到峰值。

第三季度销售额呈现稳定增长趋势,其中 9 月份销售额达到峰值。

第三季度销售额呈现稳定增长趋势,其中 9 月份销售额达到峰值。

### 月度销售数据

| 指标         | 7 月   | 8 月   | 9 月   | 季度变化 |
| ------------ | ------ | ------ | ------ | -------- |
| 总销售额     | ¥542K  | ¥598K  | ¥702K  | +29.5%   |
| 订单数量     | 6,842  | 7,523  | 9,219  | +34.7%   |
| 平均订单金额 | ¥79.20 | ¥79.49 | ¥76.15 | -3.9%    |
| 新客户数     | 1,284  | 1,502  | 2,104  | +63.9%   |

## 区域表现分析 {#regional}

华东地区贡献了最高的销售额,而华南地区则显示出最高的增长率。

华东地区贡献了最高的销售额,而华南地区则显示出最高的增长率。

华东地区贡献了最高的销售额,而华南地区则显示出最高的增长率。

华东地区贡献了最高的销售额,而华南地区则显示出最高的增长率。

### 区域销售数据

| 区域 | 销售额 | 占比  | 同比增长 | 订单数量 |
| ---- | ------ | ----- | -------- | -------- |
| 华东 | ¥623K  | 33.8% | +15.2%   | 8,142    |
| 华北 | ¥398K  | 21.6% | +12.7%   | 5,329    |
| 华南 | ¥367K  | 19.9% | +25.4%   | 4,876    |
| 华中 | ¥287K  | 15.6% | +19.8%   | 3,892    |
| 西部 | ¥167K  | 9.1%  | +21.3%   | 1,345    |

## 产品表现分析 {#product}

电子产品和家居用品类别增长最为显著,分别同比增长 32.5%和 28.7%。

电子产品和家居用品类别增长最为显著,分别同比增长 32.5%和 28.7%。

电子产品和家居用品类别增长最为显著,分别同比增长 32.5%和 28.7%。

电子产品和家居用品类别增长最为显著,分别同比增长 32.5%和 28.7%。

## 结论与建议 {#conclusion}

基于第三季度的销售表现,我们提出以下建议:

1. 加大对华南和西部地区的市场投入
2. 针对电子产品类别开发更多高附加值产品
3. 优化物流网络,缩短西部地区配送时间
4. 开展客户忠诚度计划,提高复购率
5. 第四季度重点推广家居和季节性产品

HTML 模板文件(template.html)

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>$title$</title>

    <style>
        :root {
            --primary-color: #3498db;
            --active-color: #2980b9;
            --sidebar-bg: #2c3e50;
            --text-light: #ecf0f1;
            --content-bg: #f9f9f9;
            --shadow: 0 2px 10px rgba(0,0,0,0.1);
            --card-bg: #ffffff;
            --border-radius: 8px;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', 'Microsoft YaHei', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: #333;
            background-color: #f5f7fa;
            display: flex;
            min-height: 100vh;
            overflow-x: hidden;
        }

        /* 侧边导航栏样式 */
        .sidebar {
            width: 280px;
            background: var(--sidebar-bg);
            color: var(--text-light);
            padding: 25px 0;
            height: 100vh;
            position: fixed;
            overflow-y: auto;
            box-shadow: var(--shadow);
            z-index: 100;
            transition: all 0.3s ease;
        }

        .report-title {
            padding: 0 25px 25px;
            border-bottom: 1px solid rgba(255,255,255,0.1);
            margin-bottom: 25px;
        }

        .report-title h1 {
            font-size: 1.6rem;
            margin-bottom: 8px;
            font-weight: 600;
        }

        .report-title p {
            font-size: 0.9rem;
            opacity: 0.8;
        }

        .nav-menu {
            list-style: none;
        }

        .nav-item {
            margin-bottom: 6px;
        }

        .nav-link {
            display: flex;
            align-items: center;
            padding: 14px 30px;
            color: var(--text-light);
            text-decoration: none;
            transition: all 0.3s ease;
            position: relative;
            font-weight: 500;
        }

        .nav-link:hover {
            background: rgba(255,255,255,0.1);
        }

        .nav-link.active {
            background: rgba(255,255,255,0.15);
            color: white;
            font-weight: 600;
        }

        .nav-link.active::before {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            height: 100%;
            width: 4px;
            background: var(--active-color);
        }

        .nav-link i {
            margin-right: 12px;
            font-size: 18px;
            width: 24px;
            text-align: center;
        }

        /* 主内容区域样式 */
        .main-content {
            flex: 1;
            margin-left: 280px;
            padding: 45px;
            transition: all 0.3s ease;
        }

        .section {
            margin-bottom: 65px;
            padding: 35px;
            background: var(--card-bg);
            border-radius: var(--border-radius);
            box-shadow: var(--shadow);
            transition: transform 0.3s ease, box-shadow 0.3s ease;
        }

        .section:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px rgba(0,0,0,0.1);
        }

        .section h2 {
            color: var(--primary-color);
            margin-bottom: 25px;
            padding-bottom: 18px;
            border-bottom: 2px solid #eee;
            font-size: 1.8rem;
            display: flex;
            align-items: center;
        }

        .section h2 i {
            margin-right: 12px;
            background: rgba(52, 152, 219, 0.1);
            width: 42px;
            height: 42px;
            border-radius: 50%;
            display: inline-flex;
            align-items: center;
            justify-content: center;
        }

        .data-container {
            display: flex;
            flex-wrap: wrap;
            gap: 25px;
            margin: 30px 0;
        }

        .data-box {
            flex: 1;
            min-width: 300px;
            height: 200px;
            padding: 25px;
            background: white;
            border-radius: var(--border-radius);
            box-shadow: 0 2px 15px rgba(0, 0, 0, 0.08);
            transition: all 0.3s ease;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }

        .data-box:hover {
            transform: translateY(-5px);
            box-shadow: 0 5px 20px rgba(0, 0, 0, 0.12);
        }

        .data-box h3 {
            color: var(--primary-color);
            margin-bottom: 15px;
            text-align: center;
        }

        .data-box .value {
            font-size: 2.5rem;
            font-weight: bold;
            color: #2c3e50;
            margin: 10px 0;
        }

        .data-box .change {
            font-size: 1.1rem;
            font-weight: 600;
            padding: 4px 12px;
            border-radius: 20px;
            display: inline-block;
        }

        .data-box .change.positive {
            background: rgba(46, 204, 113, 0.15);
            color: #27ae60;
        }

        .data-box .change.negative {
            background: rgba(231, 76, 60, 0.15);
            color: #c0392b;
        }

        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
            gap: 25px;
            margin: 25px 0;
        }

        .stat-card {
            background: linear-gradient(135deg, #3498db, #2c3e50);
            color: white;
            padding: 25px;
            border-radius: var(--border-radius);
            text-align: center;
            box-shadow: 0 4px 15px rgba(0,0,0,0.12);
            transition: transform 0.3s ease;
        }

        .stat-card:hover {
            transform: translateY(-5px);
        }

        .stat-value {
            font-size: 2.2rem;
            font-weight: bold;
            margin: 15px 0;
        }

        .stat-label {
            font-size: 0.95rem;
            opacity: 0.9;
        }

        .table-container {
            overflow-x: auto;
            margin: 30px 0;
            border-radius: var(--border-radius);
            box-shadow: 0 2px 15px rgba(0,0,0,0.05);
        }

        table {
            width: 100%;
            border-collapse: collapse;
            min-width: 600px;
        }

        th, td {
            padding: 15px 18px;
            text-align: left;
            border-bottom: 1px solid #eee;
        }

        th {
            background-color: #f8f9fa;
            font-weight: 600;
            color: #2c3e50;
        }

        tr:hover {
            background-color: #f5f9ff;
        }

        .insight-card {
            background: white;
            border-left: 4px solid var(--primary-color);
            padding: 20px;
            margin: 25px 0;
            border-radius: 0 var(--border-radius) var(--border-radius) 0;
            box-shadow: 0 2px 10px rgba(0,0,0,0.05);
        }

        .insight-card h4 {
            margin-bottom: 10px;
            color: var(--primary-color);
            display: flex;
            align-items: center;
        }

        .insight-card h4 i {
            margin-right: 10px;
        }

        .footer {
            text-align: center;
            margin-top: 50px;
            padding-top: 25px;
            border-top: 1px solid #eee;
            color: #7f8c8d;
            font-size: 0.95rem;
        }

        /* 响应式设计 */
        @media (max-width: 992px) {
            .sidebar {
                width: 220px;
            }

            .main-content {
                margin-left: 220px;
                padding: 30px;
            }
        }

        @media (max-width: 768px) {
            .sidebar {
                width: 100%;
                height: auto;
                position: relative;
                padding: 20px 0;
            }

            .main-content {
                margin-left: 0;
                padding: 25px;
            }

            .section {
                padding: 25px;
                margin-bottom: 45px;
            }

            .data-box {
                min-width: 100%;
                height: 180px;
                margin: 10px 0;
            }

            .data-container {
                gap: 15px;
            }
        }

        /* 打印样式优化 */
        @media print {
            body {
                display: block;
                background: white;
            }

            .sidebar {
                display: none;
            }

            .main-content {
                margin: 0;
                padding: 20px;
            }

            .section {
                box-shadow: none;
                border: 1px solid #eee;
                page-break-inside: avoid;
            }

            .stat-card, .data-box {
                box-shadow: none;
            }
        }

        /* 滚动条美化 */
        ::-webkit-scrollbar {
            width: 8px;
            height: 8px;
        }

        ::-webkit-scrollbar-track {
            background: rgba(0,0,0,0.05);
        }

        ::-webkit-scrollbar-thumb {
            background: rgba(52, 152, 219, 0.5);
            border-radius: 4px;
        }

        ::-webkit-scrollbar-thumb:hover {
            background: rgba(52, 152, 219, 0.7);
        }
    </style>

    <!-- 引入Font Awesome图标 -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
    <!-- 左侧导航菜单 -->
    <nav class="sidebar">
        <div class="report-title">
            <h1>$title$</h1>
            <p>生成日期: $date$</p>
        </div>
        <ul class="nav-menu">
            <li class="nav-item"><a href="#overview" class="nav-link"><i class="fas fa-home"></i>报告概览</a></li>
            <li class="nav-item"><a href="#sales-analysis" class="nav-link"><i class="fas fa-chart-line"></i>销售分析</a></li>
            <li class="nav-item"><a href="#regional" class="nav-link"><i class="fas fa-map-marked-alt"></i>区域表现</a></li>
            <li class="nav-item"><a href="#product" class="nav-link"><i class="fas fa-box-open"></i>产品分析</a></li>
            <li class="nav-item"><a href="#conclusion" class="nav-link"><i class="fas fa-lightbulb"></i>结论建议</a></li>
        </ul>
    </nav>

    <!-- 主内容区域 -->
    <main class="main-content">
        $body$

        <div class="footer">
            <p>本报告由Pandoc自动生成 | $author$ | © $year$</p>
        </div>
    </main>

    <script>
        // 导航菜单激活状态处理
        document.addEventListener('DOMContentLoaded', function() {
            const navLinks = document.querySelectorAll('.nav-link');
            const sections = document.querySelectorAll('.section');

            // 初始激活第一个菜单项
            setActiveNav();

            // 监听滚动事件
            window.addEventListener('scroll', setActiveNav);

            function setActiveNav() {
                let currentSection = '';

                // 确定当前显示的section
                sections.forEach(section => {
                    const sectionTop = section.offsetTop - 100;
                    if (window.scrollY >= sectionTop) {
                        currentSection = section.getAttribute('id');
                    }
                });

                // 更新导航激活状态
                navLinks.forEach(link => {
                    link.classList.remove('active');
                    if (link.getAttribute('href').substring(1) === currentSection) {
                        link.classList.add('active');
                    }
                });
            }

            // 平滑滚动效果
            navLinks.forEach(link => {
                link.addEventListener('click', function(e) {
                    e.preventDefault();
                    const targetId = this.getAttribute('href');
                    const targetSection = document.querySelector(targetId);

                    window.scrollTo({
                        top: targetSection.offsetTop - 80,
                        behavior: 'smooth'
                    });
                });
            });
        });
    </script>
</body>
</html>

生成 HTML 报告

使用以下命令将 Markdown 文件转换为 HTML 报告:

bash 复制代码
pandoc report.md -o output.html --template=template.html --standalone

命令参数说明

  • report.md: 输入的 Markdown 文件

  • -o output.html: 指定输出文件名

  • --template=template.html: 使用自定义 HTML 模板

  • --standalone: 生成完整的 HTML 文档(包含头部和尾部)

相关推荐
浩男孩7 分钟前
🍀简简单单使用 TS 封装个工具库【更新中 ✍】
前端·typescript
Shinpei27 分钟前
如何在AI流式数据中渲染mermaid图表
前端·deepseek
快起来别睡了36 分钟前
深入浅出 Event Loop:前端工程师必须掌握的运行机制
前端·javascript
user2975258761237 分钟前
别再用关键字搜了!手搓一个Vite插件,为页面上的标签打上标记
前端·javascript·vite
典学长编程38 分钟前
前端开发(HTML,CSS,VUE,JS)从入门到精通!第五天(jQuery函数库)
javascript·css·ajax·html·jquery
野区小女王43 分钟前
react调用接口渲染数据时,这些表格里的数据是被禁选的
前端·react.js·前端框架
尝尝你的优乐美1 小时前
原来前端二进制数组有这么多门道
前端·javascript·面试
前端_yu小白1 小时前
Vue2实现docx,xlsx,pptx预览
开发语言·javascript·ecmascript
金金金__1 小时前
事件循环-原理篇
javascript·浏览器
CF14年老兵1 小时前
🔥 2025 年开发者必试的 10 款 AI 工具 🚀
前端·后端·trae