Angular2: как использовать библиотеку pdfmake

Попытка использовать клиентскую библиотеку PDF pdfmake в моем проекте Angular 2 (версия = 4.2.x).

В файле .angular-cli.json я объявил js следующим образом:

"scripts": [
    "../node_modules/pdfmake/build/pdfmake.js",
    "../node_modules/pdfmake/build/vfs_fonts.js"
  ]

А затем в app.component.ts я использовал это так:

import * as pdfMake from 'pdfmake';

@Component({
selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
   pdf: any;
   downloadPdf() {
    let item = {firstName: 'Peter', lastName: 'Parker'};
    this.pdf = pdfMake;
    this.pdf.createPdf(buildPdf(item)).open();
  }
}

function buildPdf(value) {
   var pdfContent = value;
   var docDefinition = {
     content: [{
    text: 'My name is: ' + pdfContent.firstName  + ' ' + pdfContent.lastName + '.'
     }]
   }
   console.log(pdfContent);
   return docDefinition;
}

Я нажимаю ниже ошибку в консоли браузера при загрузке приложения:

Uncaught TypeError: fs.readFileSync is not a function
at Object.<anonymous> (linebreaker.js:15)
at Object.<anonymous> (linebreaker.js:161)
at Object.../../../../linebreak/src/linebreaker.js (linebreaker.js:161)
at __webpack_require__ (bootstrap b937441…:54)
at Object.../../../../pdfmake/src/textTools.js (textTools.js:4)
at __webpack_require__ (bootstrap b937441…:54)
at Object.../../../../pdfmake/src/docMeasure.js (docMeasure.js:4)
at __webpack_require__ (bootstrap b937441…:54)
at Object.../../../../pdfmake/src/layoutBuilder.js (layoutBuilder.js:7)
at __webpack_require__ (bootstrap b937441…:54)

Мой обходной путь для решения этой проблемы:

Скопируйте pdfmake.js и vfs_fonts.js в папку с ресурсами, а затем добавьте это в index.html:

<script src='assets/pdfmake.min.js'></script>
<script src='assets/vfs_fonts.js'></script>

Удалите это из app.component.ts

import * as pdfMake from 'pdfmake';

И добавьте это в app.component.ts:

declare var pdfMake: any;

Наконец, удалите это из .angular-cli.js:

"../node_modules/pdfmake/build/pdfmake.js",
"../node_modules/pdfmake/build/vfs_fonts.js"

Это работает, но это все еще обходной путь.

Кто-нибудь знает, как использовать эту библиотеку в Angular/Typscript?

Большое спасибо!


person Softhinker.com    schedule 17.07.2017    source источник


Ответы (4)


Следуя приведенной выше инструкции @benny_boe, у меня все получилось! Позвольте мне резюмировать это следующим образом:

Первый,

npm install pdfmake --save

Во-вторых, добавьте ниже к typings.d.ts:

declare module 'pdfmake/build/pdfmake.js';
declare module 'pdfmake/build/vfs_fonts.js';

В-третьих, в файле, где используется pdfMake, будь то компонент или служба, добавьте следующие строки:

import * as pdfMake from 'pdfmake/build/pdfmake.js';
import * as pdfFonts from 'pdfmake/build/vfs_fonts.js';
pdfMake.vfs = pdfFonts.pdfMake.vfs;

Наконец, используйте pdfMake.xxx() как обычно.

person Softhinker.com    schedule 18.07.2017
comment
Когда вы делаете это таким образом, вы можете получить дубликаты файла pdfmake. Попробуйте source map explorer проверить свои пакеты, если они есть в ваших vendor И ваших scripts пакетах.. - person benny_boe; 18.07.2017
comment
Да, вы правы, мне не нужно добавлять эти 2 js в раздел скриптов в .angular-cli.json. Я обновил свой пост, удалив старый второй шаг. Спасибо! - person Softhinker.com; 19.07.2017
comment
Это [импорт * как pdfMake из 'pdfmake/build/pdfmake.js';] или [импорт pdfMake из 'pdfmake/build/pdfmake';]? - person Jonathas Pacífico; 02.02.2018
comment
Если мы будем следовать этой процедуре, это вызовет проблему при сборке с помощью AOT. С вами, ребята, тоже такое бывает? - person k harish; 09.12.2018
comment
@kharish Ты пробовал там min версию...??? попробуйте добавить pdfmake/build/pdfmake.min.js или pdfmake/build/pdfmake.min - person Rahmat Ali; 21.01.2020

Итак, обо всем по порядку. Вам не нужно добавлять сторонние сценарии в .angular-cli.json И добавлять импорт в файлы TS. Ознакомьтесь с историей глобальных скриптов из Angular CLI.

Как только вы импортируете библиотеку через массив скриптов, вы не должны не импортировать ее с помощью оператора импорта в коде TypeScript...

(Для pdfmake нет типов, поэтому вам нужно объявить их при удалении файла конфигурации..)

Поэтому, если вы хотите добавить его в свой TS-файл... замените import * as pdfMake from 'pdfmake'; (это версия на стороне сервера!) на версию на стороне клиента ('pdfmake/build/pdfmake'). Вам также нужно будет добавить шрифты ('pdfmake/build/vfs_fonts'), иначе вы тоже получите ошибку.

Когда ваш импорт выглядит так, он должен работать:

import pdfMake from 'pdfmake/build/pdfmake';
import pdfFonts from 'pdfmake/build/vfs_fonts';
pdfMake.vfs = pdfFonts.pdfMake.vfs;
person benny_boe    schedule 17.07.2017
comment
Спасибо! Но это не работает, и возникает ошибка: Uncaught TypeError: Cannot read property 'pdfMake' of undefined. Пожалуйста, порекомендуйте. - person Softhinker.com; 18.07.2017
comment
Да, я заставил это работать, следуя упомянутой вами истории глобальных сценариев. Большое спасибо! Я подытожу это в другом ответе. - person Softhinker.com; 18.07.2017
comment
Рад слышать, что у вас все получилось! Я попробовал свое решение с последней бета-версией Angular CLI (1.3.0-beta.1), и оно работает. На какой ты версии? - person benny_boe; 18.07.2017

Еще один простой подход при использовании глобальных скриптов согласно angular-cli Stories Global Scripts если внимательно следовать инструкции. ЕСЛИ в библиотеке нет типов.

В файле angular-cli.json

"scripts": [
  "../node_modules/pdfmake/build/pdfmake.min.js",
  "../node_modules/pdfmake/build/vfs_fonts.js"
],

В файле src/typings.d.ts

Добавьте строку declare var pdfMake: any; ниже.

Теперь в любом месте вашего приложения доступна глобальная переменная pdfMake.

Попробуйте зарегистрировать pdfMake в конструкторе или любых методах инициализации

ngOnInit() { console.log(pdfMake); }

ВЫВОД

{
    createdPdf: f(t),
    vfs: {
        Roboto-Italic.ttf: "some long encoded string...",
        Roboto-Medium.ttf: "some long encoded string...",
        Roboto-MediumItalic.ttf: "some long encoded string...",
        Roboto-Regular.ttf: "some long encoded string...",
    }
}

Это означает, что он готов к использованию.

person Roel    schedule 29.04.2018

person    schedule
comment
Спасибо за этот фрагмент кода, который может предоставить некоторую ограниченную немедленную помощь. правильное объяснение значительно улучшит его долгосрочную ценность, показав, почему это хорошее решение проблемы и сделать его более полезным для будущих читателей с другими, похожими вопросами. Пожалуйста, отредактируйте свой ответ, чтобы добавить некоторые пояснения, включая сделанные вами предположения. - person Akin Okegbile; 03.07.2019