javascript - imprimir - Imprima un pdf sin abrirlo visualmente
imprimir varios pdf sin abrirlos windows 7 (2)
Después de pasar las últimas horas tratando de resolver esto y buscar mucho aquí es lo que he determinado ...
La especificación HTML5 Web API para impresión indica que uno de los printing steps
debe beforeprint de la printing steps
, un evento simple (un evento que no puede cancelarse), el objeto de ventana del documento que se está imprimiendo (así como cualquier contexto de navegación anidado, esto se relaciona con iframes) para permitir cambios al documento antes de imprimir. Este paso es interno al navegador y no es algo que podrá ajustar. Durante este proceso, el cuadro de diálogo de impresión del navegador a veces muestra una vista previa del archivo (Chrome lo hace) ... así que si su objetivo es no mostrar nunca el archivo al visor, es posible que esté atascado.
Lo más cercano a lograr esto que vine fue crear un archivo index.html
que tiene un botón que contiene data- * atributos que proporcionan contexto. Cambie la ruta / filename.ext en el atributo data-print-resource-uri
a un archivo local propio.
<!DOCTYPE html>
<html>
<head>
<title>Express</title>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<h1>Express</h1>
<p>Welcome to Express</p>
<button name="printFile" id="printFile" data-print-resource-uri="/binary/paycheckStub.pdf" data-print-resource-type="application/pdf">Print File</button>
<iframe name="printf" id="printf" frameborder="0"></iframe>
<script src="/javascripts/print.js"></script>
</body>
</html>
Luego, en el archivo print.js
, probé algunas cosas, pero nunca print.js
(dejando cosas diferentes con las que jugué en los comentarios).
// Reference vars
var printButton = document.getElementById(''printFile'');
var printFrame = document.getElementById(''printf'');
// onClick handler
printButton.onclick = function(evt) {
console.log(''evt: '', evt);
printBlob(''printf'', printButton.getAttribute(''data-print-resource-uri''), printButton.getAttribute(''data-print-resource-type''));
}
// Fetch the file from the server
function getFile( fileUri, fileType, callback ) {
var xhr = new XMLHttpRequest();
xhr.open(''GET'', fileUri);
xhr.responseType = ''blob'';
xhr.onload = function(e) {
// Success
if( 200 === this.status ) {
// Store as a Blob
var blob = new Blob([this.response], {type: fileType});
// Hang a URL to it
blob = URL.createObjectURL(blob);
callback(blob);
} else {
console.log(''Error Status: '', this.status);
}
};
xhr.send();
}
function printBlob(printFrame, fileUri, fileType) {
// Debugging
console.log(''inside of printBlob'');
console.log(''file URI: '', fileUri);
console.log(''file TYPE: '', fileType);
// Get the file
getFile( fileUri, fileType, function(data) {
loadAndPrint(printFrame, data, fileType);
});
}
function loadAndPrint(printFrame, file, type) {
// Debugging
console.log(''printFrame: '', printFrame);
console.log(''file: '', file);
window.frames[printFrame].src = file;
window.frames[printFrame].print();
/*
// Setup the print window content
var windowContent = ''<!DOCTYPE html>'';
windowContent += ''<html>''
windowContent += ''<head><title>Print canvas</title></head>'';
windowContent += ''<body>''
windowContent += ''<embed src="'' + file + ''" type="'' + type + ''">'';
windowContent += ''</body>'';
windowContent += ''</html>'';
// Setup the print window
var printWin = window.open('''','''',''width=340,height=260'');
printWin.document.open();
printWin.document.write(windowContent);
printWin.document.close();
printWin.focus();
printWin.print();
printWin.close();
*/
}
Creo que si logras que funcione correctamente, usar Blob
podría funcionar mejor en el método de navegador cruzado que quisieras.
Encontré algunas referencias sobre este tema que podrían ser útiles:
Lo que quiero construir es que al hacer clic en un botón quiero activar la impresión de un archivo PDF, pero sin abrirlo.
+-----------+
| Print PDF |
+-----------+
^ Click *---------> printPdf(pdfUrl)
La forma en que lo intenté por primera vez es usar un iframe:
var $iframe = null;
// This is supposed to fix the onload bug on IE, but it''s not fired
window.printIframeOnLoad = function() {
if (!$iframe.attr("src")) { return; }
var PDF = $iframe.get(0);
PDF.focus();
try {
// This doesn''t work on IE anyways
PDF.contentWindow.print();
// I think on IE we can do something like this:
// PDF.document.execCommand("print", false, null);
} catch (e) {
// If we can''t print it, we just open it in the current window
window.location = url;
}
};
function printPdf(url) {
if ($iframe) {
$iframe.remove();
}
$iframe = $(''<iframe>'', {
class: "hide",
id: "idPdf",
// Supposed to be a fix for IE
onload: "window.printIframeOnLoad()",
src: url
});
$("body").prepend($iframe);
}
Esto funciona en Safari (escritorio e iOS) y Chrome (¿podemos generalizarlo tal vez para webkit?).
En Firefox, PDF.contentWindow.print()
finaliza con un error de permission denied
(incluso el pdf se carga desde el mismo dominio).
En IE (11), el controlador de onload
simplemente no funciona.
Ahora, mi pregunta es: ¿hay alguna otra forma mejor de imprimir el pdf sin abrirlo visualmente al usuario?
El navegador cruzado es crítico aquí. Deberíamos admitir tantos navegadores como sea posible.
¿Cuál es la mejor manera de lograr esto? ¿Mi inicio es bueno? Cómo completarlo?
Ahora estamos en 2016 y siento que esto todavía es un dolor para implementar en todos los navegadores.
ACTUALIZAR : Este nvision.co/blog/tips-and-tricks/auto-print-pdf-file-open detalla una solución elegante que implica editar las propiedades de la página para la primera página y agregar una acción en el Abrir página. Funciona en todos los navegadores (ya que los navegadores ejecutarán JavaScript colocado en la sección de acciones). Requiere Adobe Acrobat Pro.
Parece que 2016 no trae nuevos avances al problema de impresión. Tuve un problema similar y para hacer el navegador cruzado de impresión, lo resolví usando PDF.JS pero tuve que hacer una adición de una sola línea a la fuente (le piden que construya sobre ella de todos modos).
La idea:
- Descargue la versión estable precompilada de https://mozilla.github.io/pdf.js/getting_started/#download y agregue las carpetas "compilar" y "web" al proyecto.
- El archivo
viewer.html
es lo queviewer.html
archivos PDF con una interfaz completa y contiene la funcionalidad de impresión. Agregué un enlace en ese archivo a mi propio JavaScript que simplemente activa window.print () después de un retraso.
El enlace agregado al espectador:
<script src="viewer.js"></script>
<!-- this autoPrint.js was added below viewer.js -->
<script src="autoPrint.js"></script>
</head>
El javascript de autoPrint.js
:
(function () {
function printWhenReady() {
if (PDFViewerApplication.initialized) {
window.print();
}
else {
window.setTimeout(printWhenReady, 3000);
}
};
printWhenReady();
})();
Podría poner llamadas a
viewer.html?file=
en el src de un iframe y ocultarlo. Tuve que usar visibilidad, no mostrar estilos debido a Firefox:<iframe src="web/viewer.html?file=abcde.pdf" style="visibility: hidden">
El resultado: el cuadro de diálogo de impresión se muestra después de un breve retraso con el PDF oculto para el usuario.
Probado en Chrome, IE, Firefox.