🎨 导出 PDF 时支持将资源文件作为附件嵌入 https://github.com/siyuan-note/siyuan/issues/7414

This commit is contained in:
Liang Ding 2023-02-23 11:18:05 +08:00
parent f003aac384
commit a576708916
No known key found for this signature in database
GPG key ID: 136F30F901A2231D
5 changed files with 54 additions and 34 deletions

View file

@ -421,7 +421,8 @@ export const initWindow = () => {
fetchPost("/api/export/processPDF", { fetchPost("/api/export/processPDF", {
id: ipcData.rootId, id: ipcData.rootId,
merge: ipcData.mergeSubdocs, merge: ipcData.mergeSubdocs,
path: pdfFilePath path: pdfFilePath,
removeAssets: ipcData.removeAssets,
}, () => { }, () => {
afterExport(pdfFilePath, msgId); afterExport(pdfFilePath, msgId);
if (ipcData.removeAssets) { if (ipcData.removeAssets) {

View file

@ -326,7 +326,8 @@ func processPDF(c *gin.Context) {
if nil != arg["merge"] { if nil != arg["merge"] {
merge = arg["merge"].(bool) merge = arg["merge"].(bool)
} }
err := model.ProcessPDF(id, path, merge) removeAssets := arg["removeAssets"].(bool)
err := model.ProcessPDF(id, path, merge, removeAssets)
if nil != err { if nil != err {
ret.Code = -1 ret.Code = -1
ret.Msg = err.Error() ret.Msg = err.Error()

View file

@ -141,6 +141,7 @@ replace github.com/mattn/go-sqlite3 => github.com/88250/go-sqlite3 v1.14.13-0.20
//replace github.com/siyuan-note/httpclient => D:\88250\httpclient //replace github.com/siyuan-note/httpclient => D:\88250\httpclient
//replace github.com/siyuan-note/filelock => D:\88250\filelock //replace github.com/siyuan-note/filelock => D:\88250\filelock
//replace github.com/88250/lute => D:\gogogo\src\github.com\88250\lute //replace github.com/88250/lute => D:\gogogo\src\github.com\88250\lute
//replace github.com/88250/pdfcpu => D:\88250\pdfcpu replace github.com/88250/pdfcpu => D:\88250\pdfcpu
//replace github.com/88250/gulu => D:\88250\gulu //replace github.com/88250/gulu => D:\88250\gulu
//replace github.com/mattn/go-sqlite3 => D:\88250\go-sqlite3 //replace github.com/mattn/go-sqlite3 => D:\88250\go-sqlite3

View file

@ -10,8 +10,6 @@ github.com/88250/gulu v1.2.3-0.20221117052724-cd06804db798 h1:sR/s/Y9wyl79ZRCUER
github.com/88250/gulu v1.2.3-0.20221117052724-cd06804db798/go.mod h1:I1qBzsksFL2ciGSuqDE7R3XW4BUMrfDgOvSXEk7FsAI= github.com/88250/gulu v1.2.3-0.20221117052724-cd06804db798/go.mod h1:I1qBzsksFL2ciGSuqDE7R3XW4BUMrfDgOvSXEk7FsAI=
github.com/88250/lute v1.7.6-0.20230220030205-b0f64d7ba66e h1:7UgFzsksh+z6IX2z+BKG3tt1TU7LJNb0zOHDbhLEaUc= github.com/88250/lute v1.7.6-0.20230220030205-b0f64d7ba66e h1:7UgFzsksh+z6IX2z+BKG3tt1TU7LJNb0zOHDbhLEaUc=
github.com/88250/lute v1.7.6-0.20230220030205-b0f64d7ba66e/go.mod h1:cEoBGi0zArPqAsp0MdG9SKinvH/xxZZWXU7sRx8vHSA= github.com/88250/lute v1.7.6-0.20230220030205-b0f64d7ba66e/go.mod h1:cEoBGi0zArPqAsp0MdG9SKinvH/xxZZWXU7sRx8vHSA=
github.com/88250/pdfcpu v0.3.14-0.20230223023428-417e2a8897ac h1:deLsfAbzg+KJy53yJDGNe/+9RZr6RR813rbMKOiW/uI=
github.com/88250/pdfcpu v0.3.14-0.20230223023428-417e2a8897ac/go.mod h1:S5YT38L/GCjVjmB4PB84PymA1qfopjEhfhTNQilLpv4=
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1 h1:48T899JQDwyyRu9yXHePYlPdHtpJfrJEUGBMH3SMBWY= github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1 h1:48T899JQDwyyRu9yXHePYlPdHtpJfrJEUGBMH3SMBWY=
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1/go.mod h1:U3pckKQIgxxkmZjV5yXQjHdGxQK0o/vEZeZ6cQsxfHw= github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1/go.mod h1:U3pckKQIgxxkmZjV5yXQjHdGxQK0o/vEZeZ6cQsxfHw=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=

View file

@ -654,7 +654,7 @@ func processIFrame(tree *parse.Tree) {
} }
} }
func ProcessPDF(id, p string, merge bool) (err error) { func ProcessPDF(id, p string, merge, removeAssets bool) (err error) {
inFile := p inFile := p
links, err := api.ListToCLinks(inFile) links, err := api.ListToCLinks(inFile)
if nil != err { if nil != err {
@ -665,8 +665,6 @@ func ProcessPDF(id, p string, merge bool) (err error) {
return links[i].Page < links[j].Page return links[i].Page < links[j].Page
}) })
pdfcpu.VersionStr = "SiYuan v" + util.Ver
bms := map[string]*pdfcpu.Bookmark{} bms := map[string]*pdfcpu.Bookmark{}
for _, link := range links { for _, link := range links {
linkID := link.URI[strings.LastIndex(link.URI, "/")+1:] linkID := link.URI[strings.LastIndex(link.URI, "/")+1:]
@ -774,38 +772,51 @@ func ProcessPDF(id, p string, merge bool) (err error) {
} }
} }
if 0 < len(assetAbsPaths) { pdfCtx, ctxErr := api.ReadContextFile(inFile)
//outFile := inFile + ".tmp" if nil != ctxErr {
//err = api.AddAttachmentsFile(inFile, outFile, assetAbsPaths, false, nil) logging.LogErrorf("read pdf context failed: %s", ctxErr)
//if nil != err { return
// logging.LogErrorf("add attachment failed: %s", err) }
// return
//}
//
//err = os.Rename(outFile, inFile)
//if nil != err {
// return
//}
assetLinks, listErr := api.ListAssetLinks(inFile) if 0 < len(assetAbsPaths) {
assetLinks, otherLinks, listErr := api.ListLinks(inFile)
if nil != listErr { if nil != listErr {
logging.LogErrorf("list asset links failed: %s", listErr) logging.LogErrorf("list asset links failed: %s", listErr)
return return
} }
pdfCtx, ctxErr := api.ReadContextFile(inFile) if _, removeErr := pdfCtx.RemoveAnnotations(nil, nil, nil, false); nil != removeErr {
if nil != ctxErr { logging.LogWarnf("remove annotations failed: %s", removeErr)
logging.LogErrorf("read pdf context failed: %s", ctxErr)
return
} }
linkMap := map[int][]*pdfcpu.IndirectRef{} linkMap := map[int][]pdfcpu.AnnotationRenderer{}
pdfCtx.RemoveAnnotations(nil, nil, nil, false) for _, link := range otherLinks {
if 1 > len(linkMap[link.Page]) {
linkMap[link.Page] = []pdfcpu.AnnotationRenderer{link}
} else {
linkMap[link.Page] = append(linkMap[link.Page], link)
}
}
attachementMap := map[int][]*pdfcpu.IndirectRef{}
now := pdfcpu.StringLiteral(pdfcpu.DateString(time.Now())) now := pdfcpu.StringLiteral(pdfcpu.DateString(time.Now()))
for _, link := range assetLinks { for _, link := range assetLinks {
link.URI = strings.ReplaceAll(link.URI, "http://127.0.0.1:6806/export/temp/", "") link.URI = strings.ReplaceAll(link.URI, "http://127.0.0.1:6806/export/temp/", "")
link.URI, _ = url.PathUnescape(link.URI) link.URI, _ = url.PathUnescape(link.URI)
if !removeAssets {
// 不移除资源文件夹的话将超链接指向资源文件夹
if 1 > len(linkMap[link.Page]) {
linkMap[link.Page] = []pdfcpu.AnnotationRenderer{link}
} else {
linkMap[link.Page] = append(linkMap[link.Page], link)
}
continue
}
// 移除资源文件夹的话使用内嵌附件
absPath, getErr := GetAssetAbsPath(link.URI) absPath, getErr := GetAssetAbsPath(link.URI)
if nil != getErr { if nil != getErr {
continue continue
@ -873,13 +884,20 @@ func ProcessPDF(id, p string, merge bool) (err error) {
} }
if 1 > len(linkMap[link.Page]) { if 1 > len(linkMap[link.Page]) {
linkMap[link.Page] = []*pdfcpu.IndirectRef{ann} attachementMap[link.Page] = []*pdfcpu.IndirectRef{ann}
} else { } else {
linkMap[link.Page] = append(linkMap[link.Page], ann) attachementMap[link.Page] = append(attachementMap[link.Page], ann)
} }
} }
for page, anns := range linkMap { if 0 < len(linkMap) {
if _, addErr := pdfCtx.AddAnnotationsMap(linkMap, false); nil != addErr {
logging.LogErrorf("add annotations map failed: %s", addErr)
}
}
// 添加附件注解指向内嵌的附件
for page, anns := range attachementMap {
pageDictIndRef, pageErr := pdfCtx.PageDictIndRef(page) pageDictIndRef, pageErr := pdfCtx.PageDictIndRef(page)
if nil != pageErr { if nil != pageErr {
logging.LogWarnf("page dict ind ref failed: %s", pageErr) logging.LogWarnf("page dict ind ref failed: %s", pageErr)
@ -926,11 +944,12 @@ func ProcessPDF(id, p string, merge bool) (err error) {
entry.Object = append(annots, array...) entry.Object = append(annots, array...)
pdfCtx.EnsureVersionForWriting() pdfCtx.EnsureVersionForWriting()
} }
}
if writeErr := api.WriteContextFile(pdfCtx, inFile); nil != writeErr { pdfcpu.VersionStr = "SiYuan v" + util.Ver
logging.LogErrorf("write pdf context failed: %s", writeErr) if writeErr := api.WriteContextFile(pdfCtx, inFile); nil != writeErr {
return logging.LogErrorf("write pdf context failed: %s", writeErr)
} return
} }
return return