Ghi chú

Thêm hỗ trợ ghi chú vào trình xem

Ghi chú trong Doconut hoạt động theo hai hướng: người dùng vẽ chúng trong widget trình duyệt và máy chủ lưu chúng theo trang, hoặc mã của bạn tạo chúng một cách lập trình và tải chúng vào một phiên mở. Dù sao chúng cũng được hiển thị trên các trang và có thể được nhúng vào các xuất PDF/PNG.

Hỗ trợ ghi chú được kiểm soát bởi khả năng cấp phép Annotation (được cấp tự động khi có giấy phép Temporary đang hoạt động).

Bật giao diện người dùng ghi chú

Ghi chú là một mô-đun Viewer, không phải là một thanh công cụ độc lập. Trang đầy đủ phải bao gồm các tài nguyên Viewer, thanh công cụ Viewer, vùng gắn Viewer và objViewer đã được khởi tạo; sau đó Ribbon Ghi chú sẽ được gắn và đính kèm vào cùng một thể hiện.

Phát ra các gói ghi chú cùng với các gói viewer — chúng được kiểm soát bằng giấy phép, vì vậy các thẻ chỉ xuất hiện khi khả năng này có sẵn:

html
@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
    IncludeViewerCss     = true,
    IncludeAnnotationCss = true   // jquery-ui.min.css + annotationBar.css
}))

@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
    IncludeJQuery             = true,
    IncludeViewerScripts      = true,
    IncludeAnnotationScripts  = true, // jquery-ui, raphael.js, annotation.js
    IncludeAnnotationBar      = true  // the embedded annotation ribbon
}))

Giữ nguyên cấu trúc Viewer đầy đủ hiển thị trong markup:

html
<nav id="toolbar" aria-label="Document viewer controls">
    <!-- Viewer controls, including the button that opens Annotation -->
</nav>
<div id="annBarMount"></div>
<div id="divDocViewer"><div id="div_ctlDoc"></div></div>

Gói Annotation tạo ra DOM Ribbon bên trong annBarMount; bạn không cần sao chép các nút hoặc markup hộp thoại của nó. Khởi tạo docViewer trước, sau đó tạo Ribbon chỉ khi máy chủ xác nhận rằng Annotation đã được cấp phép:

html
<script>
    let annBar = null;
    let currentToken = '';

    const objViewer = $('#div_ctlDoc').docViewer({
        BasePath: '/',
        ResPath: 'doconut-res/images',
        onAnnLoaded:    () => annBar?.handleAnnLoaded(),
        onAnnSaved:     () => annBar?.handleAnnSaved(),
        onAnnSaveError: () => annBar?.handleAnnSaveError(),
        onAnnClosed:    () => annBar?.handleAnnClosed(),
        onError:        (message) => console.error('Viewer error:', message)
    });

    @if (Viewer.IsAnnotationEnabled)
    {
        <text>
    annBar = $('#annBarMount').doconutAnnotationBar({
        docId: 'ctlDoc',
        getRequestParams: () => ({ token: currentToken }),
        onStatus: (message) => console.log(message),
        onToast: (message, type) => console.log(type, message),
        onLayout: () => requestAnimationFrame(() => objViewer.Refit())
    });
    annBar.attach(objViewer);
        </text>
    }
</script>

Việc lưu từ Ribbon gửi dữ liệu qua middleware (AnnSave), lưu trữ nó trong phiên tài liệu theo trang. Việc tải (AnnLoad) diễn ra tự động khi một trang có ghi chú được hiển thị. Bốn callback onAnn* giữ cho Ribbon đồng bộ với vòng đời của viewer.

Mở và đóng nó từ bất kỳ thanh công cụ Viewer nào thuộc host:

javascript
annBar.open();
annBar.close();

API công cộng của Ribbon là:

Phương thứcMục đích
attach(objViewer)Kết nối Ribbon với viewer đã được khởi tạo; yêu cầu một lần
open() / close()Bắt đầu hoặc kết thúc chỉnh sửa ghi chú
reset()Đưa Ribbon trở lại trạng thái đóng, không chỉnh sửa
isOpen() / annotating()Đọc trạng thái của Ribbon / trạng thái chỉnh sửa ghi chú của viewer
reopenEditable()Tải lại các ghi chú của trang hiện tại dưới dạng đối tượng có thể chỉnh sửa
updateActionState()Làm mới khả năng hiển thị điều khiển lưu/xóa sau khi host thay đổi
headerSlot()Lấy khe mở rộng tiêu đề tùy chọn cho các điều khiển thuộc host

onStatus, onToast, onLayout, onEditStart, và onEditEnd là các callback tùy chọn của host. Đối tượng endpoints có thể bổ sung cung cấp exportPdf, exportPng, imageUpload, và imageList; các điều khiển không có endpoint được cấu hình sẽ bị ẩn. Đối với chuỗi khởi động kết hợp Viewer, Search và Annotation, xem Bắt đầu nhanh.

Gói annotation thêm các công cụ tạo nội dung trong trình duyệt, nhưng dữ liệu vẫn thuộc về phiên tài liệu phía máy chủ được xác định bằng token. Mở lại nguồn tạo một phiên mới; lưu trữ XML hoặc phong bì annotation đã mã hoá trong ứng dụng của bạn nếu các ghi chú cần tồn tại vượt qua thời gian sống của phiên.

Xây dựng chú thích trong C#

Lấy một trình quản lý được ràng buộc với phiên mở, thêm các chú thích và tải chúng (với using Doconut.Annotations; cho các kiểu và using System.Drawing; cho Rectangle/Color):

csharp
app.MapPost("/api/annotations/load-sample", (string token, Viewer viewer) =>
{
    // Bound to the open session's page dimensions
    var manager = viewer.GetAnnotationManager(token);
    var pageCount = viewer.GetPageCount(token);

    // One stamp per page
    for (int page = 1; page <= pageCount; page++)
    {
        manager.Add(new StampAnnotation(page, new Rectangle(30, 20, 240, 90),
            $"PAGE {page}", 28, 4, Color.Maroon)
        {
            Opacity = 60,
            Rotate  = -8
        });
    }

    manager.Add(new NoteAnnotation(1, new Rectangle(420, 150, 220, 120),
        "Loaded from C# code.", Color.FromArgb(255, 255, 255, 170), 14));

    // Load into the session — the widget fetches them via AnnLoad and the
    // renderer burns them into image/PDF exports.
    viewer.LoadAnnotationData(token, manager);
    return Results.Ok();
});

Các loại chú thích

Tất cả các loại nằm trong Doconut.Annotations và kế thừa từ BaseAnnotation (số trang + Rectangle bao quanh):

LoạiGhi chú
StampAnnotationDấu tem văn bản với kích thước phông chữ, viền, màu; hỗ trợ Opacity, Rotate
NoteAnnotationGhi chú dính với văn bản, màu nền, kích thước phông chữ, TitleColor
RectangleAnnotationMàu viền + màu nền, Title/ShowTitle
CircleAnnotationViền + nền, ShowBorder
EllipseAnnotationViền + nền, ShowBorder
TriangleAnnotationMàu viền, BackColor, ShowBorder
LineAnnotationĐường thẳng với độ rộng và màu
ArrowAnnotationĐường có mũi tên; có thể đặt Direction (kiểu ArrowDirection, các hướng bắc, nam, ... , mặc định E)
FreehandAnnotationNét vẽ tự do từ các điểm FreehandData đã mã hoá
ImageAnnotationHình ảnh từ một URL. Một URL tương đối sẽ được giải quyết dựa trên máy chủ yêu cầu khi chú thích được thêm (chỉ việc tải hình ảnh xảy ra tại thời điểm đốt) — nó phải có thể truy cập được từ máy chủ (ví dụ: một tệp dưới wwwroot được phục vụ bởi UseStaticFiles)

API AnnotationManager

Thành viênMục đích
Add(BaseAnnotation)Thêm một chú thích vào hàng đợi
GetAnnotations() / GetAnnotations(int page)Kiểm tra những gì trình quản lý đang giữ
ClearAnnotations() / ClearAnnotations(int page)Xóa tất cả / theo trang
GetAnnotationData() / GetAnnotationData(int page)Chuỗi dữ liệu chú thích đã mã hoá — một phong bì Base64 (được widget tiêu thụ)
GetAnnotationXml()Dạng XML

Viewer phản chiếu các thao tác tải/đọc đối với một phiên: LoadAnnotationData(token, manager) hoặc LoadAnnotationData(token, encodedData) (phong bì Base64 từ GetAnnotationData()), LoadAnnotationXML(token, xml), GetAnnotationXML(token).

Xuất với các chú thích đã được đốt vào

csharp
// PDF of all pages with annotations rendered onto them
app.MapGet("/api/annotations/export-pdf", async (string token, Viewer viewer) =>
{
    byte[] pdf = await viewer.ExportAnnotationsToPdfAsync(token, zoom: 100);
    return Results.File(pdf, "application/pdf", "export.pdf");
});

// Or a ZIP of per-page PNGs
app.MapGet("/api/annotations/export-png-zip", async (string token, Viewer viewer) =>
{
    byte[] zip = await viewer.ExportAnnotationsToPngZipAsync(token, zoom: 100);
    return Results.File(zip, "application/zip", "annotations-png.zip");
});

Quá trình xuất sử dụng cùng bộ đốt như khi render trên màn hình, vì vậy những gì người dùng thấy là những gì file chứa.

Quy trình lưu trữ

  1. Mở tài liệu và lấy token của nó.
  2. Tải XML hoặc dữ liệu đã mã hoá đã lưu trước vào token đó.
  3. Cho phép widget đọc và chỉnh sửa các chú thích trong phiên.
  4. Lấy XML bằng GetAnnotationXML(token) khi ứng dụng của bạn quyết định lưu trữ.
  5. Xuất PDF/PNG khi cần một bản giao hàng đã được làm phẳng.
  6. Đóng phiên tài liệu.

Không sử dụng token viewer không trong suốt làm định danh chú thích cố định. Hãy gắn dữ liệu chú thích đã lưu với các định danh tài liệu và phiên bản của riêng bạn.

Bảo mật và ghi chú về việc render

  • Yêu cầu chú thích sử dụng cùng cơ chế bảo mật session/token như các yêu cầu trang.
  • Một URL ImageAnnotation tương đối được giải quyết dựa trên host của yêu cầu và phải vẫn có thể truy cập được bởi máy chủ tại thời điểm render.
  • Xác thực và kiểm soát bất kỳ URL hình ảnh do người dùng cung cấp để tránh tấn công giả mạo yêu cầu phía máy chủ.
  • Việc xuất dữ liệu áp dụng cùng quyết định giấy phép/đánh dấu tùy chỉnh như khi render trang trên màn hình.
  • Các payload tự do lớn và xuất độ phân giải cao làm tăng việc sử dụng bộ nhớ; hãy kiểm tra tài liệu thực tế và các giá trị phóng đại.

Khắc phục sự cố

Triệu chứngKiểm tra
Thanh ribbon chú thích bị thiếuAnnotation capability và bốn cờ CSS/script của chú thích
Callback lưu báo lỗiHết hạn token/session và middleware BasePath
Các chú thích C# không hiển thịĐánh số trang bắt đầu từ 1 và dữ liệu đã được tải vào token đang hoạt động
Chú thích hình ảnh hiển thị trên màn hình nhưng không xuất raMáy chủ có thể truy cập URL hình ảnh trong quá trình render
Tài liệu mở lại không có chú thíchLưu trữ XML/dữ liệu bên ngoài phiên viewer, sau đó tải vào token mới

Trang này có hữu ích không?