hyperlinks working in presentation pdf exports

This commit is contained in:
Zuzanna 2025-08-13 14:09:26 +02:00
parent d04939a0d2
commit 6de65ce6bb
4 changed files with 182 additions and 2 deletions

55
package-lock.json generated
View File

@ -48,6 +48,7 @@
"open-sans-fontface": "^1.4.0",
"openid-client": "^5.7.1",
"pako": "^2.1.0",
"pdf-lib": "^1.17.1",
"prompt-confirm": "^2.0.4",
"pull-stream": "^3.6.1",
"require-css": "0.1.10",
@ -577,6 +578,36 @@
"node": ">= 8"
}
},
"node_modules/@pdf-lib/standard-fonts": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz",
"integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==",
"license": "MIT",
"dependencies": {
"pako": "^1.0.6"
}
},
"node_modules/@pdf-lib/standard-fonts/node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
"license": "(MIT AND Zlib)"
},
"node_modules/@pdf-lib/upng": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz",
"integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==",
"license": "MIT",
"dependencies": {
"pako": "^1.0.10"
}
},
"node_modules/@pdf-lib/upng/node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
"license": "(MIT AND Zlib)"
},
"node_modules/@rollup/plugin-commonjs": {
"version": "28.0.6",
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.6.tgz",
@ -5061,6 +5092,30 @@
"node": ">=8"
}
},
"node_modules/pdf-lib": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz",
"integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==",
"license": "MIT",
"dependencies": {
"@pdf-lib/standard-fonts": "^1.0.0",
"@pdf-lib/upng": "^1.0.1",
"pako": "^1.0.11",
"tslib": "^1.11.1"
}
},
"node_modules/pdf-lib/node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
"license": "(MIT AND Zlib)"
},
"node_modules/pdf-lib/node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"license": "0BSD"
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",

View File

@ -51,6 +51,7 @@
"open-sans-fontface": "^1.4.0",
"openid-client": "^5.7.1",
"pako": "^2.1.0",
"pdf-lib": "^1.17.1",
"prompt-confirm": "^2.0.4",
"pull-stream": "^3.6.1",
"require-css": "0.1.10",

View File

@ -35,6 +35,7 @@ Fse.rmSync(oldComponentsPath, { recursive: true, force: true });
"open-sans-fontface",
"tweetnacl",
"tweetnacl-util",
"pdf-lib",
"require-css",
"requirejs",
"requirejs-plugins",

View File

@ -26,7 +26,9 @@ define([
'/common/onlyoffice/current-version.js',
'/common/onlyoffice/broken-formats.js',
'/components/pdf-lib/dist/pdf-lib.js',
'/components/file-saver/FileSaver.min.js',
'css!/components/bootstrap/dist/css/bootstrap.min.css',
'less!/components/components-font-awesome/css/font-awesome.min.css',
@ -53,7 +55,8 @@ define([
EmptySlide,
Channel,
OOCurrentVersion,
BrokenFormats)
BrokenFormats,
PDFLib)
{
var saveAs = window.saveAs;
var Nacl = window.nacl;
@ -2556,6 +2559,10 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
});
};
APP.printPdf = function (obj, cb) {
var bin = getContent();
x2tConvertData({
@ -2566,7 +2573,123 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
var md = common.getMetadataMgr().getMetadataLazy();
var type = common.getMetadataMgr().getPrivateData().ooType;
var title = md.title || md.defaultTitle || type;
var blob = new Blob([xlsData], {type: "application/pdf"});
var extractLinks = function () {
var results = [];
var m_aPairs = getEditor().WordControl.m_oDrawingDocument
?.m_oLogicDocument?.
TableId?.m_aPairs;
if (!m_aPairs || typeof m_aPairs !== 'object') {
return results;
}
var parseContent = function (contentArray, context = {}) {
if (!Array.isArray(contentArray)) return;
contentArray.forEach((contentItem, contentIndex) => {
var path = { ...context, contentIndex };
if (typeof contentItem?.Value === "string" && contentItem.Value.trim() !== "") {
results.push(
contentItem.Value
);
}
if (Array.isArray(contentItem?.Content)) {
parseContent(contentItem.Content, path);
}
});
}
for (const pairKey in m_aPairs) {
var pair = m_aPairs[pairKey];
var spTreeArray = pair?.cSld?.spTree;
if (!Array.isArray(spTreeArray)) continue;
spTreeArray.forEach((spTreeItem, spTreeIndex) => {
var contentArray = spTreeItem?.txBody?.content?.Content;
var context = { pairKey, spTreeIndex };
parseContent(contentArray, context);
});
}
return results;
}
var links = extractLinks()
var fixLinkAnnotations = async function (pdfBin, links) {
var {
PDFDocument,
PDFName,
PDFString,
PDFNumber,
} = PDFLib;
var pdfDoc = await PDFDocument.load(pdfBin);
var pages = pdfDoc.getPages();
let linkIndex = 0;
for (const page of pages) {
var annotsRef = page.node.get(PDFName.of('Annots'));
if (!annotsRef) continue;
var annots = pdfDoc.context.lookup(annotsRef);
if (!annots?.asArray) continue;
for (const annotRef of annots.asArray()) {
if (linkIndex >= links.length) break;
var annot = pdfDoc.context.lookup(annotRef);
var subtype = annot.get(PDFName.of('Subtype'));
if (!subtype || subtype.value() !== '/Link') continue;
let actionDict = annot.get(PDFName.of('A'));
if (!actionDict) {
actionDict = pdfDoc.context.obj({});
annot.set(PDFName.of('A'), actionDict);
}
var uriString = links[linkIndex];
actionDict.set(PDFName.of('S'), PDFName.of('URI'));
actionDict.set(PDFName.of('URI'), PDFString.of(uriString));
if (!annot.get(PDFName.of('Rect'))) {
annot.set(
PDFName.of('Rect'),
pdfDoc.context.obj([
PDFNumber.of(50),
PDFNumber.of(750),
PDFNumber.of(200),
PDFNumber.of(770),
]),
);
}
if (!annot.get(PDFName.of('Border'))) {
annot.set(
PDFName.of('Border'),
pdfDoc.context.obj([PDFNumber.of(0), PDFNumber.of(0), PDFNumber.of(0)]),
);
}
linkIndex++;
}
}
return await pdfDoc.save();
}
var run = async function () {
return updatedpdfBin = await fixLinkAnnotations(xlsData, links);
}
var blob;
run().then(function (updatedpdfBin) {
blob = new Blob([updatedpdfBin], { type: "application/pdf" });
saveAs(blob, APP.exportPdfName || title+'.pdf');
});
UI.removeModals();
cb();
saveAs(blob, APP.exportPdfName || title+'.pdf');