You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NextJS+Quill的Google Docs克隆中生成文档缩略图

实现Quill文档的带格式缩略图(NextJS环境)

针对你用Quill+NextJS做Google Docs克隆时,需要保留格式生成文档缩略图的需求,这里提供几个可行方案:

方案一:客户端渲染迷你Quill编辑器并转图片

利用Quill本身的渲染能力,创建一个小型的隐藏编辑器实例加载文档Delta,再通过截图工具转为图片,完全保留原格式。

实现步骤:

  1. 安装依赖:npm install quill html2canvas
  2. 在NextJS组件中动态引入Quill(避免SSR报错),并创建迷你编辑器:
import { useEffect, useRef, useState } from 'react';
import dynamic from 'next/dynamic';

// 动态导入Quill,禁用SSR
const Quill = dynamic(() => import('quill'), { ssr: false, loading: () => null });

export default function DocThumbnail({ delta }) {
  const editorRef = useRef(null);
  const [thumbnailUrl, setThumbnailUrl] = useState(null);

  useEffect(() => {
    if (!Quill || !delta) return;

    // 创建迷你编辑器容器
    const container = document.createElement('div');
    container.style.width = '300px';
    container.style.height = '200px';
    container.style.overflow = 'hidden';
    container.style.position = 'absolute';
    container.style.left = '-9999px';
    document.body.appendChild(container);

    // 初始化Quill并加载Delta
    const quill = new Quill(container, { theme: 'snow' });
    quill.setContents(delta);

    // 用html2canvas截图
    import('html2canvas').then(({ default: html2canvas }) => {
      html2canvas(container).then(canvas => {
        setThumbnailUrl(canvas.toDataURL('image/png'));
        // 清理容器
        document.body.removeChild(container);
      });
    });
  }, [delta, Quill]);

  return thumbnailUrl ? (
    <img src={thumbnailUrl} alt="文档缩略图" className="doc-thumbnail" />
  ) : (
    <div className="doc-placeholder">加载中...</div>
  );
}

方案二:服务器预生成缩略图(性能优先)

如果文档数量多,客户端截图会有性能损耗,可以在文档保存时,后端预生成带格式的缩略图并存储,前端直接加载图片文件。

实现思路:

  1. 后端用quill-delta-to-html将Delta转为HTML字符串
  2. 用Puppeteer打开这个HTML并截图,保存为图片文件(比如存到本地静态目录或云存储)
  3. 前端直接渲染存储好的图片URL

后端示例代码(Node.js):

const { QuillDeltaToHtmlConverter } = require('quill-delta-to-html');
const puppeteer = require('puppeteer');
const fs = require('fs');

async function generateDocThumbnail(delta) {
  // Delta转HTML
  const converter = new QuillDeltaToHtmlConverter(delta.ops, {});
  const html = converter.convert();

  // Puppeteer截图
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setContent(`
    <div style="width:300px;height:200px;overflow:hidden;padding:8px;">${html}</div>
  `);
  const screenshotBuffer = await page.screenshot({ type: 'png' });
  await browser.close();

  // 将buffer保存为本地文件
  const filePath = `./public/thumbnails/doc-${Date.now()}.png`;
  fs.writeFileSync(filePath, screenshotBuffer);
  return filePath.replace('./public', '');
}

方案三:轻量解析Delta渲染静态缩略图

如果不想用截图,可以直接解析Quill的Delta数据,提取前几个带格式的内容块,用React组件渲染成迷你样式,这种方式更轻量,无需额外依赖。

实现示例:

export default function LightweightDocThumbnail({ delta }) {
  if (!delta?.ops) return <div className="doc-placeholder">无内容</div>;

  // 提取前10个有效操作(可调整),过滤空内容
  const previewOps = delta.ops.slice(0, 10).filter(op => typeof op.insert === 'string' && op.insert.trim());

  return (
    <div className="light-thumbnail" style={{ width: '300px', height: '200px', overflow: 'hidden', padding: '8px', border: '1px solid #eee' }}>
      {previewOps.map((op, idx) => {
        const content = op.insert;
        const formats = op.attributes || {};

        let element = <span key={idx}>{content}</span>;
        if (formats.bold) element = <b key={idx}>{content}</b>;
        if (formats.italic) element = <i key={idx}>{content}</i>;
        if (formats.header) element = <h{formats.header} key={idx} style={{ margin: '4px 0', fontSize: `${16 - formats.header * 2}px` }}>{content}</h{formats.header}>;
        if (formats.list) element = <li key={idx} style={{ marginLeft: '16px' }}>{content}</li>;

        return element;
      })}
    </div>
  );
}

注意事项:

  • 方案一和二能完全保留Quill的所有格式(包括字体、颜色、列表等),方案三适合只需要基础格式的场景
  • NextJS中使用Quill时,务必确保在客户端环境初始化,避免SSR导致的DOM不存在问题
  • 截图时可以调整容器尺寸,匹配Google Docs缩略图的比例(比如4:3)

内容的提问来源于stack exchange,提问作者WinterSolstice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 13:36:10