const { PDFDocument } = require('pdf-lib')
// file = { fileName: 'test1.pdf, content: arraybuffer }
const originalPdf = await PDFDocument.load(file.content, { ignoreEncryption: true })
const newPdf = await PDFDocument.create()
const [firstPage] = await newPdf.copyPages(originalPdf, [0]) // <-- 0 is the first page
newPdf.addPage(firstPage)
const firstPagePdf = await newPdf.save()
file.content = Buffer.from(firstPagePdf)
Tag: PDF
[nodejs] Merge PDFs using pdf-lib
https://github.com/Hopding/pdf-lib
const { PDFDocument } = require('pdf-lib')
// files = [{ fileName: 'test1.pdf, content: arraybuffer },{ fileName: 'test2.pdf, content: arraybuffer }]
mergePdfs: async function (files) {
try {
const mergedPdf = await PDFDocument.create()
for (let file of files) {
const pdf = await PDFDocument.load(file.content)
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices())
copiedPages.forEach((page) => mergedPdf.addPage(page))
}
const mergedPdfFile = await mergedPdf.save()
const buffer = Buffer.from(mergedPdfFile)
return await buffer.toString('base64') // return as buffer or base64 encoded file
} catch (err) {
console.error(err.message)
}
}
[ABAP] Display PDF in HTML Control
DATA lt_data TYPE STANDARD TABLE OF x255.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_xstring "pdf data
TABLES
binary_tab = lt_data.
DATA(o_html) = NEW cl_gui_html_viewer( parent = cl_gui_container=>default_screen ).
* URL zu HTML holen
DATA: lv_url TYPE swk_url.
o_html->load_data( EXPORTING type = 'BIN'
subtype = 'PDF'
IMPORTING assigned_url = lv_url
CHANGING data_table = lt_data ).
* HTML anzeigen
o_html->show_url( lv_url ).
* erzwingt Anzeige über cl_gui_container=>default_screen
WRITE: / space.
[ABAP] OData – GET_STREAM implementation to return a PDF
METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.
* This method get's called when a media file is queried with $value. A binary stream will be returned.
TRY.
DATA(file_id) = VALUE zfile_id( it_key_tab[ name = 'file_id' ]-value ).
CATCH cx_sy_itab_line_not_found.
RETURN. " leave here when no file_id provided
ENDTRY.
DATA(ls_file) = get_file( file_id ) " read your file you want to return (if it's not yet a binary stream, convert it)
DATA(ls_stream) = VALUE ty_s_media_resource( value = ls_file-value
mime_type = ls_file-mimetype ). " in my case it's 'application/pdf'
" necessary to display the filename instead of $value in the viewer title
TRY.
" create pdf object
DATA(lo_fp) = cl_fp=>get_reference( ).
DATA(lo_pdfobj) = lo_fp->create_pdf_object( connection = 'ADC' ).
lo_pdfobj->set_document( pdfdata = ls_stream-value ).
" set title
lo_pdfobj->set_metadata( VALUE #( title = ls_file-filename ) ).
lo_pdfobj->execute( ).
" get pdf with title
lo_pdfobj->get_document( IMPORTING pdfdata = ls_stream-value ).
CATCH cx_fp_runtime_internal
cx_fp_runtime_system
cx_fp_runtime_usage INTO DATA(lo_fpex).
ENDTRY.
copy_data_to_ref( EXPORTING is_data = ls_stream
CHANGING cr_data = er_stream ).
" necessary for the pdf to be opened inline instead of a download (also sets the filename when downloaded)
/iwbep/if_mgw_conv_srv_runtime~set_header( VALUE #( name = 'content-disposition'
value = |inline; filename={ ls_file-filename }| ) ).
ENDMETHOD
Quick way to open a PDFViewer in your UI5 App:
const pdfViewer = new PDFViewer()
pdfViewer.setSource("/sap/opu/odata/ZMY_SEVICE" + my_path + "/$value") // my_path could be something like this "/PdfSet('file_id')"
pdfViewer.setTitle("My PDFViewer Title") // title of the popup, not the viewer
pdfViewer.open()
[PDF.js] Set light and dark theme manually
The new PDF.js viewer design Photon supports a light and a dark mode. By default, the theme is set automatically. To overwrite this, you can set the viewerCssTheme property.
I’ve embedded my PDF viewer in an iFrame like this:
<iframe id="pdf-js-viewer" src="/pdf/web/viewer.html" title="webviewer" frameborder="0" width="100%" height="700" allowfullscreen="" webkitallowfullscreen=""/>
By setting the viewerCssTheme property, you are able to change the PDF viewer theme. It can be modified using the PDFViewerApplicationOptions.set()
function and there are three possible values. The property has to be set before the Viewer is initialized. To archive this, you can listen to the event webviewerloaded (read more about it here). In my case, I also had to call _forceCssTheme()
after that.
document.addEventListener("webviewerloaded", async () => {
let pdfViewerIFrame = document.getElementById("pdf-js-viewer")
// https://github.com/mozilla/pdf.js/blob/master/web/app_options.js
pdfViewerIFrame.contentWindow.PDFViewerApplicationOptions.set("viewerCssTheme", 1) // 0=automatic theme, 1=light theme, 2=dark theme
pdfViewerIFrame.contentWindow.PDFViewerApplication._forceCssTheme()
})
[PDF.js] Allow PDF documents to disable copying in the viewer
With pull request 11789, the PDF Viewer respects the PDF property Content Copying, if the viewer option enablePermissions is set to true.
I’ve embedded my viewer in an iFrame like this:
<iframe id="pdf-js-viewer" src="/pdf/web/viewer.html" title="webviewer" frameborder="0" width="100%" height="700" allowfullscreen="" webkitallowfullscreen=""/>
The enablePermissions property can be modified using the PDFViewerApplicationOptions.set()
function. The property has to be set before the Viewer is initialized. To archive this, you can listen to the event webviewerloaded (read more about it here).
document.addEventListener("webviewerloaded", async () => {
let pdfViewerIFrame = document.getElementById("pdf-js-viewer")
//https://github.com/mozilla/pdf.js/blob/master/web/app_options.js
pdfViewerIFrame.contentWindow.PDFViewerApplicationOptions.set("enablePermissions", true) //allow PDF documents to disable copying in the viewer
pdfViewerIFrame.contentWindow.PDFViewerApplicationOptions.set("defaultUrl", "") //prevent loading default pdf
}
})
[PDF.js] Prevent loading default pdf
This can be done by appending ?file=
to the src path, like it is mentionend here.
<!-- "?file=" prevents loading the default document -->
<iframe id="pdf-js-viewer" src="/pdf/web/viewer.html?file=" title="webviewer" frameborder="0" width="100%" height="700" allowfullscreen="" webkitallowfullscreen=""/>
Or by setting the variable defaultUrl
to blank using the onload event.
document.addEventListener("webviewerloaded", async () => {
let pdfViewerIFrame = document.getElementById("pdf-js-viewer")
//https://github.com/mozilla/pdf.js/blob/master/web/app_options.js
pdfViewerIFrame.contentWindow.PDFViewerApplicationOptions.set("defaultUrl", "") //prevent loading default pdf
})
[nodejs] read and write a file
https://nodejs.dev/learn/reading-files-with-nodejs
https://nodejs.dev/learn/writing-files-with-nodejs
const fs = require("fs")
try {
// read from local folder
const localPDF = fs.readFileSync('PDFs/myFile.pdf')
//write back to local folder
fs.writeFileSync('PDFs/writtenBack.pdf', localPDF )
} catch (err) {
console.error(err)
}
Converting to Base64
try {
// read from local folder
const localPDF = fs.readFileSync('PDFs/myFile.pdf')
const localBase64 = localPDF.toString('base64')
//write back to local folder
fs.writeFileSync(`PDFs/writtenBack.pdf`, localBase64, {encoding: 'base64'})
} catch (err) {
console.error(err)
}
Reading and writing using streams with pipe
//read and write local file
const reader = fs.createReadStream("PDFs/myFile.pdf")
const writer = fs.createWriteStream('PDFs/writtenBack.pdf');
reader.pipe(writer)
[Software] Using pdfunite to merge PDF documents
First install pdfunite:
sudo apt update
sudo apt install poppler-utils
Syntax:
pdfunite source1.pdf source2.pdf merged_output.pdf
If a pdf file is located in a different folder, you have to add the path like this: $home/Downloads/source1.pdf
If you want to merge all pdf’s of the current folder you cant type:
pdfunite *.pdf merged_output.pdf
An alternative with GUI is PDF Arranger.