需要 - pdf - nano 数据
neeto-pdf-nano 添加可重复使用的 PDF 模板、 字段映射、 预览、 下载、,
和电子邮件附件到 Rails and React 应用程序.
它作为两个包裹:
neeto-pdf-engine:"铁路"发动机.@bigbinary/neeto-pdf-frontend: React 组件库.
目录
纳米能提供什么
铁路机车拥有:
- PDF 文档存储和活性存储模板附件.
- 租户范围文档 API.
- 绘制持久性和验证图.
- 服务器侧 PDF 渲染 .
- 文件克隆和输出文件名模板 .
前端软件包拥有:
- PDF 文档列表和上传流.
- 野外映射编辑器.
- 预览和下载控制.
- 电子邮件附件选择和预览组件 .
以下示例使用当前 @bigbinary/neeto-pdf-frontend/v2
进入点。 软件包还保留了现有软件包的根入点
消费者.
东道产品必须提供什么
主办方提供 拥有者 可重复使用的模板和a 数据记录 其值填充每个 PDF 。 它还拥有:
- 租户授权和产品路线.
- 外地正常化和价值格式化.
- 预览-录相页.
- 电子邮件设置和附件发送.
- 酌情进行所有者克隆和生命周期清理.
主机必须使用 Rails, Active Record, Active Survey, PostgreSQL, 以及
NeetoCommonsBackend::Api::BaseController。前端软件包使用端点
于 package.json,包括 React Query, Axios, i18next,
福尔米克,泰尔温德CSS, 需要Atoms, 需要UI, 和需要Molecules.
快开始
后端引擎
1. 安装发动机
source "NEETO_GEM_SERVER_URL" do
gem "neeto-pdf-engine"
end
bundle install
2. 复制文件迁移
db/migrate/20260706120000_create_neeto_pdf_engine_documents.rb
给它免费的宿主时间戳,然后运行:
bundle exec rails db:migrate
不运行普通引擎迁移安装器; 此寄存器包含
不相关的模板迁移 . owner_id 是一个UUID。 调整和测试复制的
如果所有者使用另一种主键类型,则首先迁移.
3. 配置所有者并渲染上下文
创建 config/initializers/neeto_pdf_engine.rb数字 :
# frozen_string_literal: true
NeetoPdfEngine.owner_class = "DocumentOwner"
NeetoPdfEngine.render_context_resolver = lambda do |owner:, record_id:|
PdfDocuments::RenderContextResolver.call(owner:, record_id:)
end
替换 DocumentOwner 与真正的模型。 一定是现在的组织
或支持 where(organization: current_organization)添加:
class DocumentOwner < ApplicationRecord
belongs_to :organization
has_many :neeto_pdf_documents,
as: :owner,
class_name: "NeetoPdfEngine::Document",
dependent: :destroy
end
执行渲染语境 :
module PdfDocuments
class RenderContextResolver
def self.call(owner:, record_id:)
record = owner.data_records.find(record_id) # Use the real association.
{
value_resolver: ValueResolver.new(owner:, record:),
filename_context: { id: record.id }
}
end
end
end
总是通过所有者找到数据记录. 数值解析器必须响应
改为 call(mapping)数字 :
module PdfDocuments
class ValueResolver
def initialize(owner:, record:)
@owner = owner
@record = record
end
def call(mapping)
return system_value(mapping["field_slug"]) if mapping["source"] == "system"
value_for(mapping["field_slug"])
end
private
attr_reader :owner, :record
def value_for(field_slug)
# Return the host-formatted value.
end
def system_value(field_slug)
case field_slug
when "form_name" then owner.name
when "submission_id" then record.id
when "submission_date" then I18n.l(record.created_at, format: :long)
else ""
end
end
end
end
内置的系统密钥是 form_name, (中文(简体) ), submission_id,以及
submission_date; 主机定义了它们的含义. 对于图像,返回 :
{
type: "image",
data: attachment.download,
content_type: attachment.blob.content_type
}
使用 image/svg+xml 用于SVG数据。 返回文本,一个数字,或 "" 其他费用
测绘.
4. 安装和保护发动机
挂载引擎 :
mount NeetoPdfEngine::Engine, at: "/neeto_pdf"
const PDF_API_BASE_URL = "/neeto_pdf/api/v1";
引擎认证和瞄准镜所有者为当前组织. 东道主
必须添加服务器授权到 NeetoPdfEngine::Api::V1::DocumentsController, (中文(简体) ),
包括采取行动. canManage 只更改用户界面.
5. 处理东道主生命周期规则
适用时,添加 NeetoPdfEngine::Document 用于主机焚化, 克隆 PDF
带有克隆所有者的文档,并保存重新映射 record_id 要克隆的数值
字段.
前端软件包
1. 安装软件包和PDF运行时间
yarn add @bigbinary/neeto-pdf-frontend [email protected] [email protected]
软件包使用主机的 Axios 大小写转换器, React 查询提供者,以及 i18next example. (原始内容存档于2018-09-29).
2. 包括样式和翻译
没有 PDF 样式表 。 保持需要UI和需要Molecules风格的功能
做尾风扫描 @bigbinary 软件包。 对于 Tailwind CSS 4, 调整此路径
相对于主机样式表 :
@import "tailwindcss" important;
@source "../../../../node_modules/@bigbinary";
标准的 neto- commons 构建负载包翻译. 其他建筑必须
合并 @bigbinary/neeto-pdf-frontend/app/javascript/src/translations/en.json
输入他们的 i18 next 资源.
3. 为PDF.js工人服务
添加:
{
"scripts": {
"sync:pdf-worker": "mkdir -p public && cp -f node_modules/pdfjs-dist/legacy/build/pdf.worker.min.mjs public/pdf.worker.min.js"
}
}
运行它之前 dev 财务报告和审定财务报表 build。结果为:
/pdf.worker.min.js
生成的工人可能在基特被忽略.
构成部分
页 次
import { PdfDocumentsPage } from "@bigbinary/neeto-pdf-frontend/v2";
const PdfDocuments = ({ ownerId, emailAttachments }) => (
<PdfDocumentsPage
apiBaseUrl="/neeto_pdf/api/v1"
canManage={canManagePdfDocuments}
emailAttachments={emailAttachments}
ownerId={ownerId}
onOpenEditor={document => openEditor(document.id)}
/>
);
该页列出表格中的文档。 上传一个直接打开编辑器 因此,绘图是下一步,而不是单独的决定.
onOpenEditor接收完整的文档对象。 两者都叫做当 在成功上传后打开行并右侧 .emailAttachments描述文档可附加的电子邮件, 如[{ key, label, dataTestId, onSelect }]。它驱动“从 PDF 到电子邮件 ” 菜单。 物品只导航; 邮件页上有附着的,不是这里.renderHeader财务报告和审定财务报表renderContent可以将页面放入主机布局.- 过
canManage当然 它只会改变UI.
上传使用 netoMolecules FileUpload。主动存储必须返回 signedId。 。 。 .
模板必须是10 MB或更少的PDF.
编辑器
import { PdfEditorPage } from "@bigbinary/neeto-pdf-frontend/v2";
<PdfEditorPage
apiBaseUrl="/neeto_pdf/api/v1"
canManage={canManagePdfDocuments}
documentId={documentId}
emailAttachments={emailAttachments}
fields={pdfFields}
homeUrl={pdfDocumentsUrl}
isPreviewLoading={isPreviewLoading}
mode={mode}
ownerId={ownerId}
previewPage={previewPage}
previewRecord={previewRecord}
previewTotal={previewTotal}
onBack={goToPdfDocuments}
onModeChange={setMode}
onPreviewPageChange={setPreviewPage}
/>;
使用真实 homeUrl。 。 。 . mode 财务报告和审定财务报表 onModeChange 仅用于
主机控制模式状态 .
字段形状
const pdfField = {
id: "field-id",
key: "stable-field-key",
recordId: "field-id",
slug: "stable-field-key",
label: "Display label",
kind: "email",
renderType: "text",
icon: EmailIcon,
typeLabel: "Email",
};
使用一个稳定 recordId,纯文本标签,以及 renderType: "image" 仅限
图像数据。 排除不能包含值的字段.
预览记录形状
const previewRecord = { id: "data-record-id" };
编辑器将这个ID发送到渲染端点. 引擎就打来
render_context_resolver,保留预览和附件渲染
值路径.
电子邮件附件控制
import {
PdfAttachmentSelector,
PdfAttachmentsPreview,
} from "@bigbinary/neeto-pdf-frontend/v2";
import { Form, Formik } from "formik";
<Formik
initialValues={{ pdfDocumentIds: persistedPdfDocumentIds }}
onSubmit={saveEmailSettings}
>
<Form>
<PdfAttachmentSelector
documents={pdfDocuments}
maxTotalSize={25 * 1024 * 1024}
/>
<PdfAttachmentsPreview documents={pdfDocuments} />
</Form>
</Formik>;
Formik: pdfDocumentIds
Frontend API: customFields.pdfDocumentIds
Rails: custom_fields["pdf_document_ids"]
许可 custom_fields[:pdf_document_ids] 作为数组。 删除或
保存前无法访问 ID 。 用同一所有者ID获取文档
编辑。 过 maxTotalSize 以字节表示,防止选择其组合
模板大小将超过电子邮件附件限制 。 当一个选择会
超过限制, 选择器保留它并解释文档大小
和剩余空间.
服务器侧渲染
render_context = PdfDocuments::RenderContextResolver.call(
owner:,
record_id: record.id
)
owner.neeto_pdf_documents.where(id: selected_pdf_document_ids).map do |document|
NeetoPdfEngine::Documents::RendererService.new(
document,
**render_context
).process
end
每项结果包括:
{
filename: "document-record-id.pdf",
mime_type: "application/pdf",
content: "<binary PDF>",
truncated_mapping_ids: []
}
主机附加或编码 content。加密的 PDF 提升
NeetoPdfEngine::EncryptedDocumentError。内置字体支持 ASCII 和
Latin-1;服务器渲染时会去掉其他字符.
API 终点
发动机安装在 /neeto_pdf数字 :
GET /neeto_pdf/api/v1/documents
POST /neeto_pdf/api/v1/documents
GET /neeto_pdf/api/v1/documents/:id
PATCH /neeto_pdf/api/v1/documents/:id
PUT /neeto_pdf/api/v1/documents/:id
PATCH /neeto_pdf/api/v1/documents/:id/template_file
POST /neeto_pdf/api/v1/documents/:id/clone
POST /neeto_pdf/api/v1/documents/:id/render
DELETE /neeto_pdf/api/v1/documents/:id
每个请求都需要 owner_id; 客户端无法选择 owner_type. 渲染器
还要求 record_id 并接受临时 mappings 不持续
他们。 上传接受已签名的 blob ID 或多部分的主动存储
template_file。 。 。 .
默认输出文件名是 :
<parameterized-document-name>-{{id}}.pdf
filename_context[:id] 替换 {{id}}。 。 。 .
测试
在发布前运行 Rails 测试套件并构建前端软件包 更改:
bundle exec rails test
yarn build
对于仅用于文档的更改,也运行:
yarn prettier --check README.md
git diff --check -- README.md
地方发展
gem "neeto-pdf-engine", path: "../neeto-pdf-nano"
对于本地前端工作,请遵循 前端软件包开发指南。 。 。 .
出版
跟着 构建和释放软件包 用于发布前端软件包和 Rails 引擎的指南.