Как разметить pdf схему для js
Перейти к содержимому

Как разметить pdf схему для js

  • автор:

Можно ли как-то загрузить на html-страницу одностраничный PDF документ и отметить на нем области

Нужно загрузить документ и отметить на нем области. Вроде есть встроенный движок в браузер, который позволяет просматривать и генерировать документы. Но можно ли их загружать и, например, создавать слой поверх документа и отмечать на нем некоторые области. Чтоб дальше сохранять dom элемент в бд и просматривать.

Отслеживать

задан 16 мар 2023 в 15:22

55 6 6 бронзовых знаков

0

Сортировка: Сброс на вариант по умолчанию

Знаете кого-то, кто может ответить? Поделитесь ссылкой на этот вопрос по почте, через Твиттер или Facebook.

  • javascript
  • html
  • pdf

Встраивание JS-скриптов в PDF для социальной инженерии

PDF (Portable Document Format) – кроссплатформенный формат представления документов в электронном виде. Он получил огромное распространение в мире и, де-факто, является стандартом обмена документами. Файлы этого формата можно открывать в любой операционной системе ровно в том же виде, в котором документ был создан. Более того, для его просмотра даже не обязательно устанавливать специальное ПО – современные браузеры имеют встроенные средства для отображения PDF.

Согласно статистике PositiveTechnologiesбольшинство всех атак совершается с использованием вредоносного программного обеспечения, а половина от всех атак проводится с использованием методов социальной инженерии.

Рисунок 1. Методы атак на организации, 2021

Причем в 55% случаев ВПО распространялось посредством электронной почты.

Рисунок 2. Способы распространения ВПО в атаках на организации, 2021

Таким образом, для проведения проверок с использованием методов социальной инженерии было бы полезно научиться отслеживать реакцию пользователей, что они будут делать с полученным документом. Причём делать это необходимо штатными средствами, никого не взламывая. JavaScript идеально подходит для этих целей

В данной статье мы кратко рассмотрим структуру PDF-файла, как и куда в него внедрять JavaScript, а также способы маскировки факта внедрения скрипта.

Структура PDF
Организация данных в памяти

PDF способен на большее, чем просто отображать текст. Он может также включать в себя изображения и другие мультимедийные элементы, может быть защищён паролем, выполнять JavaScript и многое другое.

Самая первая версия формата была разработана фирмой Adobe Systems ещё в 1993-м году с использованием ряда возможностей языка PostScript, но не сыскала особой популярности в то время. Многие плохо понимали преимущества формата и, кроме того, программа для чтения файлов была платной. Позже Adobe пересмотрела свою политику и выпустила бесплатный Acrobat Reader, переименованный позднее в Adobe Reader. С этих пор популярность формата начала неуклонно расти, с каждой версией он обрастал новыми возможностями, а с 1 июля 2008 года PDF является открытым стандартом ISO 32000.

Однако, вне зависимости от версии структура документа неизменна:

Рисунок 3. Структура PDF

1. Заголовок (header): самая первая строка файла, хранит номер версии спецификации PDF. На картинке выше представлен заголовок PDF-файла версии 1.7. Символ «%» вне строки или потока вводит комментарий в PDF.

2. Тело (body): хранит в себе все объекты PDF. Как правило — это текстовые потоки, различные мультимедийные элементы и тому подобное. Словом, тело используется для хранения всех данных документа, отображаемых пользователю.

3. Таблица ссылок (cross-reference table): таблица перекрёстных ссылок, содержащая смещения каждого объекта в памяти. Это позволяет приложению получать произвольный доступ к любому объекту документа, не читая его целиком. Каждая конкретная таблица начинается с ключевого слова «xref». Во второй строке первое число – это номер текущего объекта, а второе – количество строк в таблице.

Рисунок 4. Таблица перекрёстных ссылок

Каждый объект здесь представлен одной записью длиной 20 байтов (включая CRLF). Первые 10 байтов – это смещение объекта от начала PDF-документа до начала этого объекта. Далее следует разделитель пространства с другим числом, определяющим номер поколения объекта. После этого есть еще один разделитель пространства, за которым следуют буква «f» или «n», чтобы указать, свободен или используется объект.

Первый объект имеет идентификатор 0 и всегда содержит одну запись с номером поколения 65535, который находится во главе списка свободных объектов (обратите внимание на букву «f», что означает свободный). Последний объект в таблице перекрестных ссылок использует номер поколения 0.

1. Блок поиска таблиц объектов и ссылок (trailer): предоставляет соответствующую информацию о том, как приложение, читающее файл, должно найти таблицу перекрестных ссылок и другие специальные объекты. В трейлере также содержится информация о количестве исправлений, внесенных в документ. Все приложения для чтения PDF начинают с этого раздела.

Рисунок 5. Трейлер

«Size» здесь означает количество записей в таблице ссылок, «Root» указывает косвенную ссылку на корневой объект документа, а «Info» ссылает на информационный объект.

PDF был разработан с учётом возможности обновления. При постепенном обновлении PDF-файла изменения должны быть добавлены в конец файла, оставляя его исходное содержимое нетронутым.

Рисунок 6. Обновление pdf-файла

Дополнительные разделы перекрестных ссылок содержат только записи для объектов, которые были изменены, заменены или удалены. Удаленные объекты остаются в файле, но отмечаются флагом «f». Каждый трейлер должен быть завершен тегом «%% EOF» и должен содержать запись «Prev», которая указывает на предыдущий раздел перекрестных ссылок.

В версиях PDF версии 1.4 и выше можно указать запись Версии в словаре каталога документа, чтобы переопределить версию по умолчанию из заголовка PDF.

Типы данных

PDF поддерживает различные типы данных: булевы, числа, строки, имена, массивы, словари, потоки и нулевой объект. На числах, булевых значениях и нулевом объекте останавливаться не будем, а вот про остальные ниже.

Они представлены последовательностью символов ASCII в диапазоне от 0x21 до 0x7E, за исключением символов: %, (, ), , [, ], , / и №, которые следует экранировать символом косой черты – «\». В качестве альтернативы, каждый конкретный символ можно представлять в виде его шестнадцатеричного значения, которому предшествует символ «#». Длина имени ограничена 127-ю байтами.

Каждое имя должно начинаться с косой черты – «/». Этот символ не является частью имени, но является префиксом, указывающим на тип данных. При необходимости использования пробела или любого другого специального символа в имени, его следует закодировать шестнадцатеричной двухзначной нотацией.

Строка должна иметь длину не более 65 535 байтов. Её можно представлять как в виде обычной строки, заключённой в круглые скобки, так и в виде шестнадцатеричной последовательности, заключённой в угловые скобки. Кроме того, каждый отдельный символ можно представлять и в восьмеричном виде, например: «\164».

Массивы представлены в виде последовательности объектов любых типов, заключённых в квадратные скобки: [объект1 объект2 …]

Любой словарь в PDF является таблицей ключ/значение. Ключ обязательно должен быть представлен объектом Name, когда как значение может быть абсолютно любым. Максимальное количество записей в словаре – 4096. Словарь должен быть представлен записями, заключёнными в двойные угловые скобки: >

Объект потока представлен последовательностью байтов и никак не ограничен по длине. Объект потока представлен объектов словаря, в котором находятся некоторые ключевые слова, описывающие поток, за которым следует перевод строки и сам поток, заключённый в ключевые слова «stream» и «endstream».

В потоках также можно хранить и объекты, для этого в словаре потока нужно указать соответствующий тип – «ObjStm», задать количество объектов и смещение первого объекта, а в самом потоке первой строкой задать пары номер объекта и смещение в декодированном потоке.

Косвенные объекты

Каждый такой объект начинается с записи из двух чисел: номер объекта и его поколение. Далее следует ключевое слово «obj», за ним следует сам объект и закрывает всё это дело ключевое слово «endobj». Чтобы сослаться на такой объект косвенной ссылкой, следует указать номер объекта, его генерацию и ключевое слово «R».

О JavaScript

После того, как мы пробежались по структуре PDF, хотелось бы немного рассказать про JavaScript. Впервые возможность его использования появилась в PDF 1.3, что должно было улучшить работу с формами и валидацию пользовательского ввода. Однако, JavaScript стал также использоваться и для проведения различных атак, поэтому Adobe была вынуждена реализовать модель безопасности и в 2007 году представляет свой API.

Согласно классификации модели безопасности Adobe, функции были разделены на привилегированные и непривилегированные. Все критические функции (или те, что Adobe посчитала таковыми) выполняются в привилегированном контексте; пользователь получает предупреждение перед выполнением такой функции, которое необходимо принять для продолжения операции. Все прочие функции выполняются без каких-либо предупреждений или ограничений.

Следует обратить внимание, что не все просмотрщики поддерживают исполнение скриптов, некоторые позволяют исполнять только очень ограниченный набор функций. Кроме того, в том же Adobe Reader существует возможность принудительно отключить возможность исполнения JavaScript.

Код JavaScript в PDF должен быть представлен действием, которое задаётся в словаре следующим образом:

JavaScript API для создания и преобразования PDF-файлов

Создание, редактирование, рендеринг и преобразование PDF-документов в другие поддерживаемые форматы файлов без использования Adobe Acrobat через библиотеку JavaScript.

Aspose.PDF для JavaScript через C++ — это расширенная библиотека обработки и преобразования PDF-файлов, которая помогает разработчикам программного обеспечения создавайте веб-приложения с возможностью легко создавать, изменять и конвертировать PDF-документы. Это уникальное предложение, которое позволяет разработчикам программного обеспечения использовать возможности JavaScript для манипулирования PDF-файлами в своих собственных приложениях. Aspose.PDF для JavaScript через C++ обеспечивает высокую производительность и оптимизированные алгоритмы, обеспечивающие быструю и эффективную обработку PDF-файлов.

Aspose.PDF для JavaScript через C++ можно легко интегрировать в существующие приложения JavaScript с помощью простых и интуитивно понятных API, требующих минимальных усилий по написанию кода. В библиотеке имеется несколько важных функций для работы с PDF-документами, таких как оптимизация PDF-документов, добавление штампа в PDF-файл, добавление изображения в PDF-файл, извлечение текста из PDF-файлов, разделение PDF-файла на два файла, преобразование PDF-файла в PDF-файл. Формат изображений, шифрование и дешифрование PDF-файлов, добавление гиперссылок в PDF, добавление вложений в PDF, поддержка Unicode и многое другое.

Aspose.PDF для JavaScript через C++ можно использовать для извлечения данных из PDF-документов для анализа и обработки в таких отраслях, как здравоохранение, финансы и исследования. Разработчики программного обеспечения могут защитить свои PDF-документы, добавив защиту паролем, шифрование и цифровые подписи для предотвращения несанкционированного доступа и защиты конфиденциальной информации. Благодаря расширенным функциям, кросс-платформенной поддержке, эффективной производительности, простой интеграции, а также комплексной документации и поддержке, Aspose.PDF для JavaScript через C++ является надежным и эффективным решением для ваших потребностей в работе с PDF-файлами.

  • Краткий обзор
  • Независимость от платформы
  • Поддерживаемые форматы файлов

Краткий обзор

Обзор Aspose.PDF для JavaScript с использованием функций C++.

Rukovodstvo

статьи и идеи для разработчиков программного обеспечения и веб-разработчиков.

Создание файлов PDF в Node.js с помощью PDFKit

Введение Формат PDF — один из наиболее распространенных форматов документов для передачи информации. В динамических веб-приложениях вам может потребоваться экспортировать данные в документ, и PDF обычно является популярным вариантом. В этой статье мы обсудим, как создавать PDF-файлы в NodeJS с помощью пакета NPM pdfkit. PDFKit [https://pdfkit.org/] — это библиотека для создания PDF-файлов на JavaScript для Node.js, которая обеспечивает простой способ создания многостраничных PDF-документов для печати. Начало работы с PDFKit Let '

Время чтения: 7 мин.

Вступление

Формат PDF — один из наиболее распространенных форматов документов для передачи информации. В динамических веб-приложениях вам может потребоваться экспортировать данные в документ, и PDF обычно является популярным вариантом. В этой статье мы обсудим, как создавать PDF-файлы в NodeJS с помощью пакета NPM pdfkit .

PDFKit — это библиотека для создания PDF-файлов на JavaScript для Node.js, которая обеспечивает простой способ создания многостраничных PDF-документов для печати.

Начало работы с PDFKit

Создадим каталог проекта, cd в него и инициализируем проект Node с настройками по умолчанию:

 $ mkdir pdfkit-project $ cd pdfkit-project $ npm init -y 

Затем install pdfkit :

 $ npm install pdfkit 

Чтобы использовать модуль в проекте, мы импортируем его через require() :

 const PDFDocument = require('pdfkit'); 

Создание PDF-документа с помощью PDFKit

Чтобы создать PDF-документ, нам также нужно будет импортировать fs (файловая система). Мы конвейер содержимое нашего файла PDF в fs записываемого поток «ы , чтобы сохранить его. Давайте посмотрим, как это сделать:

 const PDFDocument = require('pdfkit'); const fs = require('fs'); let pdfDoc = new PDFDocument; pdfDoc.pipe(fs.createWriteStream('SampleDocument.pdf')); pdfDoc.text("My Sample PDF Document"); pdfDoc.end(); 

Сначала мы импортируем необходимые модули, после чего создаем экземпляр PDFDocument . Этот экземпляр является читаемым потоком. Мы направим этот поток в записываемый поток, чтобы сохранить файл.

Если вы не знакомы с тем, как работают потоки, ознакомьтесь с нашим введением в Node.js Streams .

Для этого мы используем pipe() и сохраняем полученный SampleDocument.pdf в нашем корневом каталоге. После создания мы можем добавить к нему содержимое с помощью text функции. Конечно, мы захотим в конце завершить поток end()

Когда мы запускаем код, в корневой папке нашего проекта создается PDF-файл с именем SampleDocument.pdf

 $ node index.js 

Примечание. Прежде чем пытаться перезаписать существующий файл PDF, он должен быть свободным. Т.е. все окна с этим файлом PDF должны быть закрыты, иначе программа выдаст ошибку.

Форматирование текста в файле PDF

Конечно, pdfkit позволяет нам делать гораздо больше, чем просто добавлять неформатированный текст в документ. Давайте посмотрим на некоторые функции, которые он предлагает.

Размещение текста

По умолчанию pdfkit отслеживает, где текст должен быть добавлен в документ, по сути, печатает каждый вызов функции text() в новой строке.

Вы можете изменить место печати текста на текущей странице, добавив координаты x и y того места, где вы хотите разместить текст, в качестве аргументов функции text() .

 pdfDoc.text("Text positioned at (200,200)", 200, 200); 

Это полезно, поскольку позволяет точно настроить расположение текста, особенно потому, что документы PDF имеют универсальный вид независимо от машины / ОС, на которой они открываются. Это также позволит вам, например, печатать текст поверх другого текста:

 const PDFDocument = require('pdfkit'); const fs = require('fs'); var pdfDoc = new PDFDocument; pdfDoc.pipe(fs.createWriteStream('SampleDocument.pdf')); pdfDoc.text("From Mon-Sat we will have a 10% discount on selected items!", 150, 150); pdfDoc .fillColor('red') .fontSize(17) .text("20%", 305, 150); pdfDoc.end(); 

Запуск этого кода даст нам:

Перенос текста и выравнивание

Модуль pdfkit автоматически переносит строки так, чтобы они помещались между полями или по width (при написании текста в столбцах). Другими словами, для параметра lineBreak по умолчанию установлено значение true Вы можете изменить его на false при вызове функции text() :

 pdfDoc.text("very long text ".repeat(20), < lineBreak : false >); 

Новые страницы также добавляются автоматически по мере необходимости, т. Е. Как только контент, который вы хотите добавить, не помещается на текущей странице целиком. Однако вы также можете переключиться на следующую страницу перед заполнением предыдущей, просто позвонив:

 pdfDoc.addPage(); 

Что касается выравнивания, pdfkit предоставляет нам обычные параметры

  • left (по умолчанию), right , по center и по justify . Обратите внимание, что установка определенного выравнивания с параметром lineBreak установленным на false , не будет работать, даже если текст может уместиться в строке.

Как и lineBreak , align устанавливается путем передачи объекта, содержащего пары ключ-значение, в функцию text() Давайте посмотрим на несколько примеров выравнивания:

 const PDFDocument = require('pdfkit'); const fs = require('fs'); var pdfDoc = new PDFDocument; pdfDoc.pipe(fs.createWriteStream('text_alignment.pdf')); pdfDoc.text("This text is left aligned", < align: 'left'>) pdfDoc.text("This text is at the center", < align: 'center'>) pdfDoc.text("This text is right aligned", < align: 'right'>) pdfDoc.text("This text needs to be slightly longer so that we can see that justification actually works as intended", < align: 'justify'>) pdfDoc.end(); 

Выполнение приведенного выше кода даст нам PDF-файл, который выглядит следующим образом:

Стилизация текста

Модуль pdfkit также предоставляет параметры, которые можно использовать для стилизации текста в ваших PDF-документах. Мы рассмотрим некоторые из наиболее важных вариантов стилизации, полный список которых вы можете найти в Руководстве в формате PDF .

Мы можем передать различные параметры в виде пар ключ-значение функции text() , а также связать несколько других функций перед вызовом text() вообще.

Очень важно отметить, что связанные функции, такие как fillColor() (а затем font() , fontSize() и т. Д.), Будут влиять на весь текст после этого вызова:

 const PDFDocument = require('pdfkit'); const fs = require('fs'); var pdfDoc = new PDFDocument; pdfDoc.pipe(fs.createWriteStream('text_styling.pdf')); pdfDoc .fillColor('blue') .text("This is a link", < link: 'https://pdfkit.org/docs/guide.pdf', underline: true >); pdfDoc .fillColor('black') .text("This text is underlined", < underline: true >); pdfDoc.text("This text is italicized", < oblique: true >); pdfDoc.text("This text is striked-through", < strike: true >); pdfDoc.end(); 

Запуск этого кода приведет к созданию PDF-файла со следующим содержанием:

Изменение стилей в середине абзаца немного сложнее, поскольку объединение нескольких text() по умолчанию добавляет новую строку после каждой. Мы можем избежать этого, установив для параметра lineBreak первого вызова text() false :

 const PDFDocument = require('pdfkit'); const fs = require('fs'); var pdfDoc = new PDFDocument; pdfDoc.pipe(fs.createWriteStream('text_styling2.pdf')); pdfDoc .fillColor('blue') .text("This text is blue and italicized", ) .fillColor('red') .text(" This text is red"); pdfDoc.end(); 

Что даст нам желаемый результат:

Создание списков

Чтобы добавить список элементов в документ PDF, PDFDocument имеет функцию list() которая принимает массив строковых элементов (или вложенные массивы строк) и отображает их в виде маркированного списка:

 const PDFDocument = require('pdfkit'); const fs = require('fs'); let pdfDoc = new PDFDocument; pdfDoc.pipe(fs.createWriteStream('lists.pdf')); let myArrayOfItems = ['Item 1', 'Item 2', 'Item 3', 'Item 4']; pdfDoc.list(myArrayOfItems); // Move down a bit to provide space between lists pdfDoc.moveDown(0.5); let innerList = ['Nested Item 1', 'Nested Item 2']; let nestedArrayOfItems = ['Example of a nested list', innerList]; pdfDoc.list(nestedArrayOfItems); pdfDoc.end(); 
Шрифты

PDFKit поставляется с 14 стандартными шрифтами, которые можно использовать в документах PDF. Любой из этих шрифтов можно передать функции font() PDFDocument и связать с text() :

 pdfDoc.font('Times-Roman').text('A text in Times Roman') 

Вы также можете добавить дополнительные шрифты, передав путь к файлу шрифта в качестве аргумента функции font() , а также имя конкретного шрифта, который вы хотите, если файл содержит набор шрифтов. В качестве альтернативы вы можете дать новому шрифту имя, чтобы к нему можно было получить доступ по этому имени, а не по пути к файлу:

 pdfDoc.registerFont('Name of the font', '/file_path', 'specific_font_name_in_case_of_a_collection') 

Вызовы font() могут быть связаны с другими функциями, как в fillColor() .

Вы также можете установить размер шрифта с помощью функции fontSize() . Давайте посмотрим на несколько примеров:

 const PDFDocument = require('pdfkit'); const fs = require('fs'); let pdfDoc = new PDFDocument; pdfDoc.pipe(fs.createWriteStream('fonts.pdf')); pdfDoc.font('ZapfDingbats').text('This is a symbolic font.'); pdfDoc.font('Times-Roman').fontSize(25).fillColor('blue').text('You can set a color for any font'); pdfDoc.font('Courier').fontSize(5).fillColor('black').text('Some text to demonstrate.'); pdfDoc.end(); 

Запустив это, мы получим следующий PDF-файл в качестве вывода:

Добавление изображений

Еще одна распространенная вещь, которую вы можете добавить в свои PDF-файлы, — это изображения. Вы можете вызвать image() в экземпляре документа и передать путь или URI изображения, которое вы хотите включить.

Вы также можете установить такие параметры, как ширина, высота, горизонтальное и вертикальное выравнивание изображения, передав объект, содержащий пары ключ-значение, в качестве аргумента функции image() . По умолчанию изображения загружаются в исходном размере.

Если выставить width и height — изображение будет растянуто в соответствии с заданными параметрами. Если один из них не указан, изображение масштабируется пропорционально указанному параметру:

 const PDFDocument = require('pdfkit'); const fs = require('fs'); let pdfDoc = new PDFDocument; pdfDoc.pipe(fs.createWriteStream('images.pdf')); pdfDoc.text('By default, the image is loaded in its full size:') pdfDoc.image('raspberries.jpg'); pdfDoc.moveDown(0.5) pdfDoc.text('Scaled to fit width and height') pdfDoc.image('raspberries.jpg', ); pdfDoc.moveDown(0.5) pdfDoc.text('Scaled to fit width') pdfDoc.image('raspberries.jpg', ); pdfDoc.end(); 

Запуск этого кода даст нам:

Вы также можете масштабировать изображение, задав коэффициент scale Кроме того, вы можете задать fit или cover , при котором изображение будет масштабировано, чтобы соответствовать предоставленному прямоугольнику или покрывать его, соответственно. Если вы предоставляете fit или cover , вы также можете установить горизонтальное выравнивание ( align ) и вертикальное выравнивание ( valign ):

 const PDFDocument = require('pdfkit'); const fs = require('fs'); let pdfDoc = new PDFDocument; pdfDoc.pipe(fs.createWriteStream('images.pdf')); pdfDoc.text('Scaled by a factor, keeps the original proportions:') pdfDoc.image('raspberries.jpg', ); pdfDoc.moveDown(0.5) pdfDoc.text('Fit with horizontal alignment:') pdfDoc.image('raspberries.jpg', ); pdfDoc.end(); 

Заключение

В этой статье мы увидели, как сгенерировать PDF-файлы в Node.js с помощью PDFKit. Мы изучили некоторые варианты форматирования текста и способы добавления изображений в наши файлы. В библиотеке есть обширная документация , в которой гораздо больше говорится о создании файлов PDF в приложениях Node.js.

Licensed under CC BY-NC-SA 4.0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *