关于 integrate-file-viewer
用于在 Dune 应用中集成 CogniteFileViewer 以预览 CDF 文件的技能,涵盖依赖和 Vite 配置、PDF.js worker 设置、支持格式及交互。
主要功能
- 01安装查看器依赖
- 02配置 PDF.js worker
- 03设置 Vite 不预打包 pdfjs-dist
- 04预览 PDF、Office、图像和文本
- 05支持缩放、平移和注释
适用场景
- 01为 Dune 应用添加文件预览
- 02通过 CDF Document Preview API 呈现 Office 文档
- 03从注释跳转到关联文件
MCP 相关
查看器使用 Dune SDK 访问 CDF 文件。Office 文档通过 CDF Document Preview API 转换。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cognitedata/ dune-skills --skill integrate-file-viewer安装后在 Claude Code 中输入/integrate-file-viewer确认已加载。
详细介绍
集成 CogniteFileViewer
将 CogniteFileViewer 添加到此 Dune 应用,以预览 CDF 文件(PDF、图像、文本)。
你的任务
按顺序完成以下步骤。修改文件前,先阅读每个文件。
步骤 1 — 了解应用
开始操作前,先阅读以下文件:
package.json— 检查包管理器(packageManager字段或锁文件)和现有依赖项vite.config.ts— 了解当前的 Vite 配置- 要添加文件查看器的组件
步骤 2 — 安装依赖项
- pnpm →
pnpm add "github:cognitedata/dune-industrial-components#semver:*" react-pdf - npm →
npm install "github:cognitedata/dune-industrial-components#semver:*" react-pdf - yarn →
yarn add "github:cognitedata/dune-industrial-components#semver:*" react-pdf
pdfjs-dist 会以正确版本作为 react-pdf 的依赖项安装,无需单独安装。
步骤 3 — 配置 PDF.js worker
使用方应用必须配置 PDF.js worker,以确保 worker 版本与 react-pdf 安装包中包含的 pdfjs-dist 版本一致。
在使用 CogniteFileViewer 的同一文件中添加此设置(模块执行顺序很重要):
import { pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs',
import.meta.url,
).toString();
pnpm 用户: pnpm 的严格链接可能会导致浏览器无法解析
pdfjs-dist。可以将pdfjs-dist添加为直接依赖项(pnpm add pdfjs-dist),也可以将public-hoist-pattern[]=pdfjs-dist添加到.npmrc。
步骤 4 — 配置 Vite
在 vite.config.ts 中添加 optimizeDeps.exclude: ['pdfjs-dist'],以防止 Vite 预打包 pdfjs-dist(这会导致 worker 无法正常工作):
export default defineConfig({
// ... existing config ...
optimizeDeps: {
exclude: ['pdfjs-dist'],
},
});
步骤 5 — 使用组件
在需要预览文件的位置导入并渲染 CogniteFileViewer。
import { CogniteFileViewer } from '@cognite/dune-industrial-components/file-viewer';
通过 useDune() 钩子获取 sdk(每个 Dune 应用中均已提供):
import { useDune } from '@cognite/dune';
const { sdk } = useDune();
支持的文件类型
| 类型 | 格式 |
|---|---|
.pdf — 页面导航、缩放、平移、图表注释叠加层 | |
| Office 文档 | Word、PowerPoint、Excel、ODS、ODP、ODT、RTF、TSV — 通过 CDF Document Preview API 转换为 PDF,然后以与 PDF 相同的方式渲染 |
| 图像 | JPEG、PNG、WebP、SVG、TIFF — 缩放、平移、旋转 |
| 文本 | .txt、.csv、.json — 以预格式化文本的形式渲染 |
| 其他 | 回退到 renderUnsupported |
最简用法
只需这些即可 — 缩放、平移和触控手势均由组件内部处理:
<CogniteFileViewer
source={{ type: 'internalId', id: file.id }}
client={sdk}
style={{ width: '100%', height: '600px' }}
/>
组件必须设置明确的高度。 如果父元素没有明确的高度,文件查看器将收缩至零高度。请始终通过
style、className或父容器设置height。
文件来源
传入以下三种来源类型之一:
// By instance ID (data-modelled file — enables annotations)
<CogniteFileViewer
source={{ type: 'instanceId', space: 'my-space', externalId: 'my-file' }}
client={sdk}
/>
// By CDF internal ID
<CogniteFileViewer
source={{ type: 'internalId', id: 12345 }}
client={sdk}
/>
// By direct URL
<CogniteFileViewer
source={{ type: 'url', url: 'https://...', mimeType: 'application/pdf' }}
/>
如果有 instanceId,优先使用它 — 这是唯一能启用图表注释叠加层的来源类型。通过 sdk.files.list() 列出文件时,请先检查 file.instanceId:
source={
file.instanceId
? { type: 'instanceId', space: file.instanceId.space, externalId: file.instanceId.externalId }
: { type: 'internalId', id: file.id }
}
完整属性参考
<CogniteFileViewer
// Required
source={source}
client={sdk} // required for instanceId and internalId sources
// PDF pagination
page={page} // controlled current page (1-indexed)
onPageChange={setPage}
onDocumentLoad={({ numPages }) => setNumPages(numPages)}
// Zoom & pan (works on PDF and images)
zoom={zoom} // 1 = 100%; Ctrl/Cmd+wheel, pinch-to-zoom, and middle-click drag built in
onZoomChange={setZoom}
minZoom={0.25} // default
maxZoom={5} // default
panOffset={pan} // controlled pan offset; resets on page change
onPanChange={setPan}
// Fit mode
fitMode="width" // 'width' fits to container width; 'page' fits entire page in container
// Rotation (PDFs and images)
rotation={rotation} // 0 | 90 | 180 | 270
// Diagram annotations (instanceId sources only)
showAnnotations={true} // default
onAnnotationClick={(annotation) => { /* annotation.linkedResource has space + externalId */ }}
onAnnotationHover={(annotation) => {}}
// Custom annotation tooltip (replaces native <title> tooltip)
renderAnnotationTooltip={(annotation, rect) => (
<div style={{
position: 'absolute',
left: rect.x + rect.width,
top: rect.y,
zIndex: 11,
}}>
{annotation.text}
</div>
)}
// Custom overlay (SVG paths, highlights, drawings — works on PDF and images)
renderOverlay={({ width, height, originalWidth, originalHeight, pageNumber, rotation }) => (
<svg
width={width}
height={height}
viewBox={`0 0 ${originalWidth} ${originalHeight}`}
preserveAspectRatio="none"
style={{ position: 'absolute', top: 0, left: 0, pointerEvents: 'all' }}
>
<path d="..." stroke="cyan" fill="none" />
</svg>
)}
// Custom renderers (all optional)
renderLoading={() => <MySpinner />}
renderError={(error) => <MyError message={error.message} />}
renderUnsupported={(mimeType) => <div>Cannot preview {mimeType}</div>}
// Layout
className="..."
style={{ width: '100%', height: '100%' }}
/>
提示与技巧
源文件更改时重置页面、缩放和旋转。 切换文件时,组件不会自动重置这些设置 — 请自行处理:
const navigateToFile = (file: FileInfo) => {
setSelectedFile(file);
setPage(1);
setZoom(1);
setRotation(0);
};
仅当 numPages > 0 时显示分页 UI。
onDocumentLoad 只会对 PDF 触发。确定存在可分页的页面后,再渲染分页控件:
{numPages > 0 && (
<>
<button disabled={page <= 1} onClick={() => setPage(p => p - 1)}>‹</button>
<span>{page} / {numPages}</span>
<button disabled={page >= numPages} onClick={() => setPage(p => p + 1)}>›</button>
</>
)}
点击注释 → 导航到关联文件。
annotation.linkedResource 包含关联 CDF 实例的 space 和 externalId。将其与 file.instanceId 匹配即可导航:
onAnnotationClick={(annotation) => {
if (!annotation.linkedResource) return;
const { space, externalId } = annotation.linkedResource;
const linked = files.find(
f => f.instanceId?.space === space && f.instanceId?.externalId === externalId
);
if (linked) navigateToFile(linked);
}}
内置触控支持。 在触控设备上,双指捏合缩放和双指拖动平移会自动生效。无需配置。
在桌面设备上,按住鼠标中键拖动即可平移(放大时)。鼠标左键仍可用于点击注释和选择文本。
按住 Ctrl/Cmd 并滚动滚轮可朝光标方向缩放 — 此功能也已内置。如果需要以编程方式添加缩放按钮或持久化缩放状态,请接入 zoom/onZoomChange;否则无需额外设置即可使用。
renderOverlay 接收页面的原始尺寸(originalWidth、originalHeight),因此你可以在原始坐标空间中设置 SVG viewBox。以 PDF 点或图像像素坐标绘制的路径,在任何缩放级别下都能正确映射到渲染后的页面。
常见问题
| 问题 | 原因 | 解决方法 |
|---|---|---|
Failed to resolve module specifier 'pdf.worker.mjs' | 未配置 Worker | 在使用 CogniteFileViewer 的同一个文件中,添加步骤 3 中的 Worker 设置 |
API version does not match Worker version | 应用与 react-pdf 之间的 pdfjs-dist 版本不匹配 | 不要单独安装 pdfjs-dist — 由 react-pdf 提供即可。如果已安装,请将其移除 |
| 注释始终不显示 | instanceId 为 undefined — 未提供时会禁用注释叠加层 | 使用 instanceId 源,或回退并接受经典文件不显示注释 |
| 注释显示但内容为空 | 文件在 CDF 中没有 CogniteDiagramAnnotation 边 | 这是预期行为 — 只有同步到数据模型的 P&ID/图纸文件才有注释 |
| 查看器高度变为零 | 父级未设置明确的高度 | 通过 style、className 或父级 CSS 设置 height |