J'essaie de créer un fichier PDF) à partir d'un flux binaire que je reçois en réponse à une demande Ajax.
Via XmlHttpRequest
je reçois les données suivantes:
%PDF-1.4....
.....
....hole data representing the file
....
%% EOF
Ce que j’ai essayé jusqu’à présent, c’est d’incorporer mes données via data:uri
. Maintenant, il n'y a rien de mal à cela et cela fonctionne bien. Malheureusement, cela ne fonctionne pas dans IE9 et Firefox. Une raison possible peut être que FF et IE9 ont des problèmes avec cet usage du data-uri
.
Maintenant, je cherche une solution qui fonctionne pour tous les navigateurs. Voici mon code:
// responseText encoding
pdfText = $.base64.decode($.trim(pdfText));
// Now pdfText contains %PDF-1.4 ...... data...... %%EOF
var winlogicalname = "detailPDF";
var winparams = 'dependent=yes,locationbar=no,scrollbars=yes,menubar=yes,'+
'resizable,screenX=50,screenY=50,width=850,height=1050';
var htmlText = '<embed width=100% height=100%'
+ ' type="application/pdf"'
+ ' src="data:application/pdf,'
+ escape(pdfText)
+ '"></embed>';
// Open PDF in new browser window
var detailWindow = window.open ("", winlogicalname, winparams);
detailWindow.document.write(htmlText);
detailWindow.document.close();
Comme je l’ai dit, cela fonctionne très bien avec Opera et Chrome (Safari n’a pas été testé)). Utilisation de IE ou FF ouvrira une nouvelle fenêtre vierge.
Existe-t-il une solution telle que la création d’un fichier PDF sur un système de fichiers afin de permettre à l’utilisateur de le télécharger?)? J'ai besoin d’une solution qui fonctionne dans tous les navigateurs, du moins dans IE, FF, Opera, etc. Chrome et Safari.
Je n'ai pas la permission de modifier l'implémentation du service Web. Il fallait donc que ce soit une solution côté client. Des idées?
Existe-t-il une solution telle que la création d’un fichier pdf sur un système de fichiers afin de laisser l’utilisateur le télécharger?
Essayez de définir responseType
sur XMLHttpRequest
sur blob
, en substituant download
attribut à a
élément pour window.open
pour permettre le téléchargement de la réponse de XMLHttpRequest
comme .pdf
fichier
var request = new XMLHttpRequest();
request.open("GET", "/path/to/pdf", true);
request.responseType = "blob";
request.onload = function (e) {
if (this.status === 200) {
// `blob` response
console.log(this.response);
// create `objectURL` of `this.response` : `.pdf` as `Blob`
var file = window.URL.createObjectURL(this.response);
var a = document.createElement("a");
a.href = file;
a.download = this.response.name || "detailPDF";
document.body.appendChild(a);
a.click();
// remove `a` following `Save As` dialog,
// `window` regains `focus`
window.onfocus = function () {
document.body.removeChild(a)
}
};
};
request.send();
Je réalise que la question est plutôt ancienne, mais voici la solution que j'ai proposée aujourd'hui:
doSomethingToRequestData().then(function(downloadedFile) {
// create a download anchor tag
var downloadLink = document.createElement('a');
downloadLink.target = '_blank';
downloadLink.download = 'name_to_give_saved_file.pdf';
// convert downloaded data to a Blob
var blob = new Blob([downloadedFile.data], { type: 'application/pdf' });
// create an object URL from the Blob
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
// set object URL as the anchor's href
downloadLink.href = downloadUrl;
// append the anchor to document body
document.body.append(downloadLink);
// fire a click event on the anchor
downloadLink.click();
// cleanup: remove element and revoke object URL
document.body.removeChild(downloadLink);
URL.revokeObjectURL(downloadUrl);
}
J'ai changé ça:
var htmlText = '<embed width=100% height=100%'
+ ' type="application/pdf"'
+ ' src="data:application/pdf,'
+ escape(pdfText)
+ '"></embed>';
à
var htmlText = '<embed width=100% height=100%'
+ ' type="application/pdf"'
+ ' src="data:application/pdf;base64,'
+ escape(pdfText)
+ '"></embed>';
et cela a fonctionné pour moi.
Je travaille dans PHP et utilise une fonction pour décoder les données binaires renvoyées par le serveur. J'extrais les informations d'une entrée dans un fichier file.php et je vis le fichier via mon serveur et tous les navigateurs. afficher l'artefact pdf.
<?php
$data = 'dfjhdfjhdfjhdfjhjhdfjhdfjhdfjhdfdfjhdf==blah...blah...blah..'
$data = base64_decode($data);
header("Content-type: application/pdf");
header("Content-Length:" . strlen($data ));
header("Content-Disposition: inline; filename=label.pdf");
print $data;
exit(1);
?>
Détectez le navigateur et utilisez Data-URI pour Chrome et utilisez PDF.js comme ci-dessous pour les autres navigateurs.
PDFJS.getDocument(url_of_pdf)
.then(function(pdf) {
return pdf.getPage(1);
})
.then(function(page) {
// get a viewport
var scale = 1.5;
var viewport = page.getViewport(scale);
// get or create a canvas
var canvas = ...;
canvas.width = viewport.width;
canvas.height = viewport.height;
// render a page
page.render({
canvasContext: canvas.getContext('2d'),
viewport: viewport
});
})
.catch(function(err) {
// deal with errors here!
});
J'ai récemment vu une autre question sur ce sujet ( le streaming de fichiers PDF dans iframe à l'aide de dataurl ne fonctionne qu'en chrome ).
J'ai construit des fichiers PDF au format ast et les ai transmis au navigateur. Je les créais d'abord avec fdf, puis avec une classe de pdf que j'ai moi-même écrite. Dans chaque cas, le pdf était créé à partir de données extraites d'un objet COM basé sur quelques paramètres GET transmis via l'URL.
En regardant vos données envoyées reçues dans l'appel ajax, il semble que vous y soyez presque. Je n'ai pas joué avec le code depuis deux ans et je ne l'ai pas documenté aussi bien que je l'aurais voulu, mais - je pense que tout ce que vous avez à faire est de définir l'objectif d'un iframe comme étant l'URL. vous obtenez le pdf de. Bien que cela puisse ne pas fonctionner - le fichier qui remplace le pdf peut également devoir supprimer un en-tête de réponse HTML en premier.
En un mot, voici le code de sortie que j'ai utilisé:
//We send to a browser
header('Content-Type: application/pdf');
if(headers_sent())
$this->Error('Some data has already been output, can\'t send PDF file');
header('Content-Length: '.strlen($this->buffer));
header('Content-Disposition: inline; filename="'.$name.'"');
header('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public');
ini_set('zlib.output_compression','0');
echo $this->buffer;
Donc, sans voir le texte complet de la réponse de l'appel ajax, je ne peux pas vraiment savoir de quoi il s'agit, bien que je sois enclin à penser que le code qui produit le pdf que vous demandez n'est peut-être que l'équivalent du dernier. ligne dans le code ci-dessus. Si c'est le code que vous contrôlez, j'essaierai de définir les en-têtes - de cette façon, le navigateur ne pourra traiter que le texte de la réponse - vous n'avez pas à vous soucier de quoi que ce soit.
J'ai simplement construit une URL pour le pdf que je voulais (un calendrier), puis j'ai créé une chaîne de caractères représentant le code html d'un iframe du fichier souhaité, id, etc., qui utilisait l'URL construite telle que src. Dès que j'ai défini le code HTML interne d'un div sur la chaîne HTML construite, le navigateur a demandé le fichier PDF, puis l'a affiché lors de sa réception.
function showPdfTt(studentId)
{
var url, tgt;
title = byId("popupTitle");
title.innerHTML = "Timetable for " + studentId;
tgt = byId("popupContent");
url = "pdftimetable.php?";
url += "id="+studentId;
url += "&type=Student";
tgt.innerHTML = "<iframe onload=\"centerElem(byId('box'))\" src='"+url+"' width=\"700px\" height=\"500px\"></iframe>";
}
EDIT: oublié de mentionner - vous pouvez envoyer des pdf binaires de cette manière. Les flux qu’ils contiennent n’ont pas besoin d’être encodés en ascii85 ou en hexadécimal. J'ai utilisé flate sur tous les flux du pdf et tout a bien fonctionné.
La réponse de @alexandre avec base64 fait l'affaire.
La raison pour laquelle cela fonctionne pour IE est ici
https://en.m.wikipedia.org/wiki/Data_URI_scheme
Sous en-tête 'format' où il est écrit
Certains navigateurs (Chrome, Opera, Safari, Firefox) acceptent un ordre non standard si les deux types de caractères sont fournis: base64 et; charset, tandis qu'Internet Explorer exige que la spécification du jeu de caractères précède le jeton base64.
Vous pouvez utiliser PDF.js pour créer PDF à partir de javascript ... il est facile de coder ... espérons que cela résoudra vos doutes !!!
Cordialement!