суббота, 3 ноября 2012 г.

О том как вставить JavaScript-код в PDF-файл


Полезный совет 

Как вставить JavaScript-код в PDF-файл

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

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

Делать мы все это будем с помощью C#, WPF и библиотеки iTextSharp. Интерфейс программы сейчас выглядит вот так:



Надо заметить, что эта программа - несколько урезанная версия веб-сервиса, делающего, по сути, то же самое.

В программе используются 2 плана: бесплатный и платный. Бесплатный - с рекламой, платный - без рекламы. Мы будем компилировать программу для бесплатного аккаунта.

1./// <summary>
2./// План аккаунта
3./// </summary>
4.enum Plan { free, hard };
5.const Plan option = Plan.free;
Также нам понадобится файл с JavaScript-кодом, который мы будем внедрять в PDF.

1.//
2.string fileWithJavaScript = "JSSubscribe.dat";
Дальше проверяем кодировку у этого файла, нам нужна UTF-8, чтобы не было проблем при внедрении.

1.string directory = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
2.fileWithJavaScript = System.IO.Path.Combine(directory, fileWithJavaScript);
3.if (!IsUTF8File(fileWithJavaScript)) RecodeFileToUTF8(fileWithJavaScript);
Для этого используем функцию IsUTF8File() и RecodeFileToUTF8(). Здесь нам понадобится бесплатная библиотека, которая так и называется - Utf8Checker.

01./// <summary>
02./// Проверяет, является ли кодировка файла UTF-8
03./// </summary>
04./// <param name="path">Имя файла</param>
05./// <returns>Кодировка UTF-8?</returns>
06.static bool IsUTF8File(string path)
07.{
08.Utf8Checker checker = new Utf8Checker();
09.using (Stream stream = File.OpenRead(path)) return (checker.IsUtf8(stream));
10.}
11./// <summary>
12./// Перекодирует файл в UTF-8
13./// </summary>
14./// <param name="fileName">Имя файла</param>
15.static void RecodeFileToUTF8(string fileName)
16.{
17.string tempStringWithText;
18.using (StreamReader reader = new StreamReader(File.OpenRead(fileName), Encoding.GetEncoding(1251))) tempStringWithText = reader.ReadToEnd();
19.FileInfo f = new FileInfo(fileName);
20.f.Delete();
21.using (StreamWriter writer = new StreamWriter(File.OpenWrite(fileName), Encoding.UTF8)) writer.Write(tempStringWithText);
22.}
Далее по нажатию на кнопку "Открыть" запрашиваем файл у пользователя.

01.private void OpenCmdExecuted(object sender, ExecutedRoutedEventArgs e)
02.{
03.statBarText.Text = "Ждите";
04.// Создать диалоговое окно открытия файла, отображающее только файлы Excel
05.OpenFileDialog openDlg = new OpenFileDialog();
06.openDlg.Filter = "Файлы PDF |*.pdf";
07.if (true == openDlg.ShowDialog())
08.{
09.// Загрузить название файла
10.string filename = openDlg.FileName;
11.// Отобразить строку в TextBox
12.txtData.Text = filename;
13.}
14.statBarText.Text = "Готово";
15.}
Затем пользователь заполняет указанные в графическом интерфейсе поля, и нажимает на кнопку "Вставить форму подписки":

01.private void SaveCmdExecuted(object sender, ExecutedRoutedEventArgs e)
02.{
03.statBarText.Text = "Ждите, идет обработка данных";
04.// Сохранить данные из TextBox в файле с тем же именем
05.if (IsValidForm(sender))
06.{
07.string stringWithJavaScript = CustomizeFileWithJavaScript(fileWithJavaScript, int.Parse(uid.Text),int.Parse(did.Text), offerInForm.Text, buttonTextInForm.Text, option);
08.SaveFileDialog saveDlg = new SaveFileDialog();
09.saveDlg.Filter = "Файлы PDF |*.pdf";
10.if (true == saveDlg.ShowDialog())
11.{
12.// Загрузить название файла
13.string filename = saveDlg.FileName;
14.try
15.{
16.IncludeJSInFile(stringWithJavaScript, txtData.Text, filename);
17.}
18.catch (Exception ex)
19.{
20.MessageBox.Show(ex.Message);
21.}
22.}
23.statBarText.Text = "Вставка формы подписки в pdf завершена.";
24.}
25.}
26./// <summary>
27./// Вставляет JavaScript в pdf
28./// </summary>
29./// <param name="stringWithJavaScript">Строка с кодом JavaScript, который необходимо вставить</param>
30./// <param name="inputPDFpath">Pdf, в который нужно вставить JavaScript</param>
31./// <param name="outputPDFpath">Pdf со вставленным JavaScript</param>
32.static void IncludeJSInFile(string stringWithJavaScript, string inputPDFpath, string outputPDFpath)
33.{
34.PdfReader reader = new PdfReader(inputPDFpath);
35.Document document = new Document();
36.PdfWriter writer;
37.try
38.{
39.writer = PdfWriter.GetInstance(document, new FileStream(outputPDFpath, FileMode.Create));
40.}
41.catch (IOException ex)
42.{
43.Exception error = new Exception("Закройте файл", ex);
44.throw error;
45.}
46.document.Open();
47.PdfContentByte cb = writer.DirectContent;
48.PdfImportedPage page;
49.for (int i = 1; i <= reader.NumberOfPages; i++)
50.{
51.document.SetPageSize(reader.GetPageSizeWithRotation(i));
52.document.NewPage();
53.page = writer.GetImportedPage(reader, i);
54.cb.AddTemplate(page, 0, 0);
55.}
56.PdfAction jAction = PdfAction.JavaScript(stringWithJavaScript, writer, true);
57.writer.AddJavaScript(jAction);
58.document.Close();
59.Console.WriteLine("Вставка JavaScript в pdf завершена.");
60.}
Функция IsValidForm() проверяет правильность введенных полей, а CustomizeFileWithJavaScript() настраивает форму подписки в зависимости от плана.

Интерфейс с заполненными полями будет выглядеть вот так:



Пример PDF со вставленным JavaScript можно скачать по ссылке:Пример файла с JavaScript.pdf http://seesharp.ru/wp-content/uploads/2012/11/%D0%9A%D0%B0%D0%BA-%D1%81%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-%D1%80%D0%B5%D0%B7%D1%8E%D0%BC%D0%B5.pdf . Надо заметить, что JavaScript будет работать только в Adobe PDF Reader. 

Ксения Кузнецова,
руководитель проекта SeeSharp.ru 

Комментариев нет:

Отправить комментарий