mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 01:27:26 +08:00
This commit is contained in:
1 parent
fb3a9e8148
commit
6525b01bab
4 files changed
+49
-14
No files matched your search
+16
-4
@@ -1535,18 +1535,30 @@ async function downloadAttachment(attachment) {
|
|||||||
updateControls();
|
updateControls();
|
||||||
setBusy(true, "正在读取附件", null, "正在读取附件");
|
setBusy(true, "正在读取附件", null, "正在读取附件");
|
||||||
try {
|
try {
|
||||||
const result = await callWASM("ofdgoAttachmentData", attachment.id);
|
const file = window.showSaveFilePicker ? await window.showSaveFilePicker({ suggestedName: attachment.fileName }) : null;
|
||||||
if (openSeq !== state.openSeq) {
|
if (openSeq !== state.openSeq) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
downloadBytes(result.bytes, "application/octet-stream", attachment.fileName);
|
const result = await callWASM("ofdgoExportAttachment", attachment.id, file);
|
||||||
setStatus(`附件下载完成 ${formatBytes(result.bytes.length)}`);
|
if (openSeq !== state.openSeq) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (result.blob) {
|
||||||
|
downloadBytes(result.blob, result.mime, attachment.fileName);
|
||||||
|
}
|
||||||
|
setStatus(`附件下载完成 ${formatBytes(result.size)}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (openSeq === state.openSeq) {
|
if (openSeq === state.openSeq) {
|
||||||
|
if (err.name === "AbortError") {
|
||||||
|
setStatus("下载已取消");
|
||||||
|
} else {
|
||||||
showError(err, false);
|
showError(err, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
state.exporting = false;
|
state.exporting = false;
|
||||||
|
state.exportRequestID = 0;
|
||||||
|
el.cancelExportButton.hidden = true;
|
||||||
if (openSeq === state.openSeq) {
|
if (openSeq === state.openSeq) {
|
||||||
setBusy(false);
|
setBusy(false);
|
||||||
updateControls();
|
updateControls();
|
||||||
@@ -3416,7 +3428,7 @@ async function callWASM(name, ...args) {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const id = ++wasmRequestID;
|
const id = ++wasmRequestID;
|
||||||
wasmRequests.set(id, { resolve, reject, openSeq: state.openSeq });
|
wasmRequests.set(id, { resolve, reject, openSeq: state.openSeq });
|
||||||
if (name === "ofdgoExportPage" || name === "ofdgoExportDocument") {
|
if (name === "ofdgoExportPage" || name === "ofdgoExportDocument" || name === "ofdgoExportAttachment") {
|
||||||
state.exportRequestID = id;
|
state.exportRequestID = id;
|
||||||
el.cancelExportButton.hidden = false;
|
el.cancelExportButton.hidden = false;
|
||||||
el.cancelExportButton.disabled = false;
|
el.cancelExportButton.disabled = false;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ self.onmessage = ({ data }) => {
|
|||||||
exports.get(data.id)?.abort();
|
exports.get(data.id)?.abort();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (data.name === "ofdgoExportPage" || data.name === "ofdgoExportDocument") {
|
if (data.name === "ofdgoExportPage" || data.name === "ofdgoExportDocument" || data.name === "ofdgoExportAttachment") {
|
||||||
exports.set(data.id, new AbortController());
|
exports.set(data.id, new AbortController());
|
||||||
}
|
}
|
||||||
pending = pending.then(() => handleMessage(data));
|
pending = pending.then(() => handleMessage(data));
|
||||||
|
|||||||
+16
-5
@@ -21,6 +21,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
|
|
||||||
"github.com/xiaoqidun/ofdgo"
|
"github.com/xiaoqidun/ofdgo"
|
||||||
@@ -81,7 +82,6 @@ func RunWASM() {
|
|||||||
registerCallback("ofdgoOpen", openDocument)
|
registerCallback("ofdgoOpen", openDocument)
|
||||||
registerCallback("ofdgoConfigure", configureDocument)
|
registerCallback("ofdgoConfigure", configureDocument)
|
||||||
registerCallback("ofdgoDocumentInfo", documentInfo)
|
registerCallback("ofdgoDocumentInfo", documentInfo)
|
||||||
registerCallback("ofdgoAttachmentData", attachmentData)
|
|
||||||
registerCallback("ofdgoRenderPage", renderPage)
|
registerCallback("ofdgoRenderPage", renderPage)
|
||||||
registerCallback("ofdgoSVGFontData", svgFontData)
|
registerCallback("ofdgoSVGFontData", svgFontData)
|
||||||
registerCallback("ofdgoSearchPage", searchPage)
|
registerCallback("ofdgoSearchPage", searchPage)
|
||||||
@@ -90,6 +90,7 @@ func RunWASM() {
|
|||||||
registerCallback("ofdgoParsePageRange", parsePageRange)
|
registerCallback("ofdgoParsePageRange", parsePageRange)
|
||||||
registerExportCallback("ofdgoExportPage", exportPage)
|
registerExportCallback("ofdgoExportPage", exportPage)
|
||||||
registerExportCallback("ofdgoExportDocument", exportDocument)
|
registerExportCallback("ofdgoExportDocument", exportDocument)
|
||||||
|
registerExportCallback("ofdgoExportAttachment", exportAttachment)
|
||||||
registerCallback("ofdgoMatchFontFiles", matchFontFiles)
|
registerCallback("ofdgoMatchFontFiles", matchFontFiles)
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
@@ -207,18 +208,28 @@ func documentInfo(args []js.Value) (any, error) {
|
|||||||
return currentSession.Info(), nil
|
return currentSession.Info(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// attachmentData 读取附件数据
|
// exportAttachment 分块导出附件
|
||||||
// 入参: args 浏览器参数
|
// 入参: args 浏览器参数
|
||||||
// 返回: any 附件数据, error 错误信息
|
// 返回: any 附件数据, error 错误信息
|
||||||
func attachmentData(args []js.Value) (any, error) {
|
func exportAttachment(args []js.Value) (any, error) {
|
||||||
if currentSession == nil {
|
if currentSession == nil {
|
||||||
return nil, fmt.Errorf("ofd document is not opened")
|
return nil, fmt.Errorf("ofd document is not opened")
|
||||||
}
|
}
|
||||||
data, err := currentSession.Reader.AttachmentData(args[0].String())
|
stream, err := currentSession.Reader.OpenAttachment(args[0].String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return successResult(map[string]any{"bytes": bytesToJS(data)}), nil
|
defer stream.Close()
|
||||||
|
writer := bufio.NewWriterSize(exportWriter{write: args[1]}, 1<<20)
|
||||||
|
if _, err := io.Copy(writer, stream); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := writer.Flush(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return successResult(map[string]any{
|
||||||
|
"mime": "application/octet-stream",
|
||||||
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// svgFontData 读取SVG字体资源
|
// svgFontData 读取SVG字体资源
|
||||||
|
|||||||
+16
-4
@@ -543,22 +543,34 @@ func (r *Reader) Attachments() ([]Attachment, error) {
|
|||||||
return doc.Attachments.Attachment, nil
|
return doc.Attachments.Attachment, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AttachmentData 获取附件文件数据
|
// OpenAttachment 打开附件文件流,调用方负责关闭,完整读取后校验ZIP数据
|
||||||
// 入参: id 附件标识
|
// 入参: id 附件标识
|
||||||
// 返回: []byte 附件数据, error 错误信息
|
// 返回: io.ReadCloser 附件文件流, error 错误信息
|
||||||
func (r *Reader) AttachmentData(id string) ([]byte, error) {
|
func (r *Reader) OpenAttachment(id string) (io.ReadCloser, error) {
|
||||||
attachments, err := r.Attachments()
|
attachments, err := r.Attachments()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, attachment := range attachments {
|
for _, attachment := range attachments {
|
||||||
if attachment.ID == id {
|
if attachment.ID == id {
|
||||||
return r.ResData(attachment.FileLoc)
|
return r.openFile(r.ResPath(attachment.FileLoc))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("attachment not found: %s", id)
|
return nil, fmt.Errorf("attachment not found: %s", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AttachmentData 获取附件文件数据
|
||||||
|
// 入参: id 附件标识
|
||||||
|
// 返回: []byte 附件数据, error 错误信息
|
||||||
|
func (r *Reader) AttachmentData(id string) ([]byte, error) {
|
||||||
|
stream, err := r.OpenAttachment(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer stream.Close()
|
||||||
|
return io.ReadAll(stream)
|
||||||
|
}
|
||||||
|
|
||||||
// CustomTags 获取自定义标引
|
// CustomTags 获取自定义标引
|
||||||
// 返回: []CustomTag 自定义标引列表, error 错误信息
|
// 返回: []CustomTag 自定义标引列表, error 错误信息
|
||||||
func (r *Reader) CustomTags() ([]CustomTag, error) {
|
func (r *Reader) CustomTags() ([]CustomTag, error) {
|
||||||
|
|||||||
Reference in new issue
Block a user