Mozilla pdf.js, How to I specify the filename for download?
Asked Answered
S

3

10

I pass the location of the php file that contains the following code as parameter to the viewer.html file and it is displayed correctly but when clicking the download button in the pdf viewer the document name is always document.pdf. This poses a problem because of how many mobile users will be downloading files only to discover that all of their files have the the name document.pdf and that they (for most mobile browsers) can't change the filename before downloading.

Do I have to pass some arbitrary parameter to the file or redirect to self with the filename appended?

<?php
$content = "a binary representation of my pdf";
header("Content-type: application/pdf");
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="someFile.pdf"');
echo $content;
?>
Shirley answered 27/6, 2014 at 16:53 Comment(5)
Get rid of the quotes around the filenameConvolution
No bacon. Same Results.Shirley
Only other thing I can think of is take off "attachment; "Convolution
Also did not work. Thanks though for the quotes, didn't know thatShirley
I looked at some of my code and I guess it doesn't actually matter if the quotes are there or not, unless there's a space in the name, just like with HTML tag attributes.Convolution
C
10

I've run into this same issue. From the pdf.js's viewer.js source:

function getPDFFileNameFromURL(url) {
  var reURI = /^(?:([^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
  //            SCHEME      HOST         1.PATH  2.QUERY   3.REF
  // Pattern to get last matching NAME.pdf
  var reFilename = /[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
  var splitURI = reURI.exec(url);
  var suggestedFilename = reFilename.exec(splitURI[1]) ||
                           reFilename.exec(splitURI[2]) ||
                           reFilename.exec(splitURI[3]);
  if (suggestedFilename) {
    suggestedFilename = suggestedFilename[0];
    if (suggestedFilename.indexOf('%') != -1) {
      // URL-encoded %2Fpath%2Fto%2Ffile.pdf should be file.pdf
      try {
        suggestedFilename =
          reFilename.exec(decodeURIComponent(suggestedFilename))[0];
      } catch(e) { // Possible (extremely rare) errors:
        // URIError "Malformed URI", e.g. for "%AA.pdf"
        // TypeError "null has no properties", e.g. for "%2F.pdf"
      }
    }
  }
  return suggestedFilename || 'document.pdf';
}

So the majic needs to come from the URL via the reURI regexp.

What you need to do is this:

http://domain.com/path/to/Named.pdf
http://domain.com/path/to/your/api?fileId=123&saveName=Named.pdf

Each of these will result in a save as filename of Named.pdf thanks to the regexp code above.

Chewning answered 13/8, 2015 at 14:23 Comment(1)
Its worth mentioning that PDFViewerApplication has setTitleUsingUrl(). You can use it to specify the file name for downloading . PDFViewerApplication.setTitleUsingUrl('mypdf.com/the-pdf.pdf');Flout
G
5

Based on comments

You can add this to wherever you're using the viewer.js file.

setTimeout(() => {
  // Wait for PDFViewerApplication object to exist
  PDFViewerApplication.setTitleUsingUrl('custom-file.pdf');
}, 10);

Then when you download the PDF it will have that filename

Glarus answered 11/11, 2020 at 3:53 Comment(0)
H
-1

In my case it only worked when I changed the viewer code itself, because the pdf is passed in the src of the iframe in blob format, I'm using Nuxt js 3. I extracted and placed the lib files in the public folder.

in the file /public/pdfjs-4....-dist/web/viewer.mjs I made the following changes:

first find the function async run(config) {...} and make the following changes img 1

Then find the async function open(args) {...} and make the following changes img 2

Now when you pass the fileName=NamedFile.pdf parameter in the iframe src, the file will be downloaded with this name.

<template>
<div class="h-full w-full">
    <ClientOnly>
        <iframe
            v-if="documentUrl"
            class="rounded-md border border-slate-400"
            title="PDF"
            width="100%"
            :height="telaMenor ? '360rem' : '660rem'"
            :src="`/pdfjs-4.6.82-dist/web/viewer.html?file=${documentUrl}&fileName=${fileName}.pdf`"
        ></iframe>
    </ClientOnly>
</div>

This solved my problem, but I hope that in the future they will improve the lib for this purpose.

Haught answered 12/9 at 14:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.