jsPDF Поврежденные PDF-файлы?

Я пытаюсь создать файл PDF с помощью JavaScript, используя jsPDF. У меня есть небольшая тестовая страница. По сути, у меня есть кнопка загрузки PDF, которая берет изображение base64 из диапазона и использует его для файла imgData. Затем я пытаюсь addImage преобразовать данные изображения в pdf, а затем сохранить их. Кажется, все работает, он создает PDF и предлагает загрузить. Однако, когда я пытаюсь просмотреть PDF-файл с помощью xpdf или Foxit Reader, мне говорят, что PDF-файл поврежден. Я неправильно создал этот PDF-файл? Моя веб-страница довольно длинная, поэтому я поместил ее в Pastebin.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />   
<script type="text/javascript" src="js/jquery/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="js/jquery/jquery-ui-1.8.17.custom.min.js"></script>
<script type="text/javascript" src="../jspdf.js"></script>
<script type="text/javascript" src="../libs/FileSaver.js/FileSaver.js"></script>
<script type="text/javascript" src="../libs/BlobBuilder.js/BlobBuilder.js"></script>
<script type="text/javascript" src="../jspdf.plugin.addimage.js"></script>
<script type="text/javascript" src="../jspdf.plugin.standard_fonts_metrics.js"></script>
<script type="text/javascript" src="../jspdf.plugin.split_text_to_size.js"></script>
<script type="text/javascript" src="../jspdf.plugin.from_html.js"></script>
<script type="text/javascript" src="js/basic.js"></script>
<title>Sup!</title>
<script>
function changeCan() {
  var c = document.getElementById("myCanvas");
  var ctx = c.getContext("2d");
  ctx.fillStyle="#FF0000";
  ctx.fillRect(0,0,128,128);
}
function changeCan3() {
  var c = document.getElementById("myCanvas");
  var ctx = c.getContext("2d");
  ctx.fillStyle="#FFFFFF";
  ctx.fillRect(0,0,128,128);
  var image = new Image();
  image.src = document.getElementById("3span").innerHTML;
  ctx.drawImage(image,0,0);
}
function changeCan4() {
  var imgData = document.getElementById("3span").innerHTML;
  window.alert(imgData.length);
  var doc = new jsPDF();
  doc.addImage(imgData, 'JPEG', 15, 40, 128, 128);
  doc.save('Test.pdf');
}
</script>
</head>
<body>
  Yo!<hr>
  <canvas id="myCanvas" width="128" height="128"></canvas><hr>
  <button type="button" onClick="changeCan()">Change Me To Red!</button>
  <button type="button" onClick="changeCan3()">Change Me To Span!</button>
  <button type="button" onClick="changeCan4()">Download Me!</button>
  <hr>
  <span id="3span" style="display:none;">B64 DATA HERE</span>
</body>
</html>

person 0xhughes    schedule 21.01.2013    source источник
comment
В вашем 3span DIV innerHTML содержит data:image/jpeg;base64,. Это требуется/необходимо? Просто мысль, я не знаю эту библиотеку jsPDF, но мне интересно, она мне скоро понадобится :)   -  person JScoobyCed    schedule 21.01.2013
comment
Что ж, часть data:image/jpeg;base64, кажется необходимой для другой части тестовой страницы, с которой я дурачился, которая меняла холст на графику смеющегося человека. Также на веб-странице jsPDF jspdf.com пример с изображением кошки показывает заголовок data:image/jpeg;base64,, если хотите. @JScoobyCed Так что я не совсем уверен, нужен он или нет, я могу попытаться быстро удалить его и создать другой PDF-файл!   -  person 0xhughes    schedule 21.01.2013
comment
@JScoobyCed Я быстро удалил этот кусок информации из данных base64, и и холст, и PDF вышли из строя. Я не слишком беспокоюсь о холсте, это просто для смеха. PDF правда не заработал, вот на ошибку FireBug плевать, getJpegSize could not find the size of the image [Break On This Error] throw new Error('getJpegSize could not find the size of the image'); Я посмотрел код в .js файле из его библиотеки и толком не могу сказать что именно он делает. Захват определенных символов, получение длины и выполнение некоторых математических операций с этой информацией.   -  person 0xhughes    schedule 21.01.2013
comment
Я попробовал ваш код, и все, что он генерирует в PDF, это этот текст: [object Uint8Array]. Так что я думаю, что это не повреждено, а что-то не полностью сгенерировано. Не могу больше помочь, чем то, что мне нужно сначала прочитать о jsPDF, и я не могу этого сделать сейчас. Удачи.   -  person JScoobyCed    schedule 21.01.2013
comment
Эй, спасибо за попытку! Вероятно, это было предупреждение, используйте его для отладки :) Удачи вам и в будущем.   -  person 0xhughes    schedule 21.01.2013
comment
Я неправильно прочитал ваш комментарий о попытке кода @JScoobyCed, я посмотрел PDF и увидел, о чем вы говорите. Должно быть, мне просто что-то не хватает в том, как я обрабатываю данные base64 или что-то в этом роде... когда я выясню это, я отправлю ответ! Надеюсь, у вас не возникнет особых проблем, когда вы рассмотрите возможность реализации jsPDF :)   -  person 0xhughes    schedule 22.01.2013


Ответы (3)


У меня была аналогичная проблема, и вот как она решается. Я использовал Blob.js, canvas-toBlob, FileSaver. Я также заметил, что последний BlobBuilder.min.js работает некорректно, поэтому вместо этого я использовал BlobBuilder.js.

var content = canvas.toDataURL('image/jpeg');
var doc = new jsPDF('landscape');
doc.addImage(content, 'JPEG', 0, 0);

var data = doc.output();
var buffer = new ArrayBuffer(data.length);
var array = new Uint8Array(buffer);

for (var i = 0; i < data.length; i++) {
    array[i] = data.charCodeAt(i);
}

var blob = new Blob(
    [array],
    {type: 'application/pdf', encoding: 'raw'}
);

saveAs(blob, filename);
person mtasic85    schedule 06.02.2013
comment
Очень кратко, я проверю это, когда у меня будет время после работы! Однако один вопрос: в начале вы захватываете контент с холста, в моем сценарии загрузка изображений происходит с локального компьютера. (Сценарий генерирует веб-страницу и данные изображения для нее). Если у меня уже есть DataURL, определенный в диапазоне, могу ли я просто использовать var content = getElementByID(SPANID).innerHtml ? Внутренний html — это toDataURL ASCII, сгенерированный сценарием. Спасибо за отличный ответ, я обязательно изучу ваш метод и посмотрю, как он работает! - person 0xhughes; 07.02.2013
comment
Я тестировал ваше решение, но получил PDF-файл типа name.pdf-1.part. Есть ли способ получить name.pdf? - person Jefferson; 11.02.2013
comment
Я не нашел способа избавиться от расширения .part. Я думаю, что моя версия FireFox (12) просто не совместима с jsPDF. Я обновил свой FireFox до версии 18.0.2, и мой исходный скрипт заработал, хотя у него все еще было это расширение .part. Я не уверен, почему это происходит. Должно быть что-то на стороне библиотеки. К сожалению, я хотел бы предложить некоторую кросс-браузерную совместимость для моей веб-страницы. Думаю, мне придется настроить своих клиентов на использование последней версии FireFox. На github jsPDF было отправлено множество вопросов. Возможно, мы получим хорошее обновление! - person 0xhughes; 12.02.2013
comment
@Jeff Кроме того, я хотел добавить немного информации общего назначения. Если вы хотите сгенерировать файл PDF, я читал веб-сайт, где кто-то вручную создал файл PDF с помощью только своего текстового редактора. Я еще не пробовал, но вполне возможно создать свою собственную маленькую функцию для создания некоторых PDF-файлов на стороне клиента, в зависимости от того, насколько вы предприимчивы и насколько динамичными будут ваши PDF-файлы. mariomalwareanalysis.blogspot.com/2012/02/ Я не проверял его метод, но это может быть началом, если вы хотите приключений ;) - person 0xhughes; 12.02.2013
comment
Эти расширения .part действительно прикольные :) Используете ли вы какие-либо расширения/аддоны для загрузки в FF? Можете ли вы проверить это в Chrome? Какую ОС вы используете? - person mtasic85; 23.02.2013
comment
@ mtasic85 Нет, я не использую никаких расширений для загрузки, использую обычный способ, я использую Linux. - person Jefferson; 12.03.2013

Я использовал версию jsPDF 1.3.4, и она работала.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.4/jspdf.min.js"></script>
person XChoopa    schedule 04.05.2017

У меня была аналогичная проблема с типом изображения png: PDF был поврежден при открытии с помощью Adobe Reader.

Изменение его на jpeg решило это!

// Before : Corrupted PDF file when opened with Adobe Reader
var imgData = canvas.toDataURL('image/png');
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'png', 0, 0, 210, 295);

// After : Working
var imgData = canvas.toDataURL('image/jpeg');
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'jpeg', 0, 0, 210, 295);
person v.nivuahc    schedule 10.01.2017