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

Моя проблема в том, что после отправки PDF пользователю, когда пользователь открывает форму, данные не могут быть сохранены. Исходный PDF-файл, который используется в качестве шаблона, можно заполнить и сохранить. Каким-то образом в процессе использования iTextSharp форма теряет права на использование. Есть ли способ сохранить права на использование при использовании iTextSharp?

Я надеюсь, что кто-то здесь сможет указать, что происходит не так, или указать мне правильное направление. Спасибо за ваше время и помощь.

Ниже приведен код:

using Dapper;
using iTextSharp.text.pdf;
using NLog;
using PilotDispatch.Domain.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data.OleDb;
using System.IO;
using System.Linq;

namespace eTicketPdfFactory
{
    class Program
    {
        const string TemplateItextPdfPath = @"C:\PDF\Factory\eTicketFormPortrait.pdf";
        const string OutputItextPdfPath = @"C:\PDF\Factory\eTicketFormPortraitOut.pdf";


    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

        static void Main(string[] args)
        {
            var logid = string.Empty;
            if (args.Length > 0)
            {
                logid = args[0];
            }
            else
            {
                Logger.Error("No LogId supplied");
                return;
            }

            var rundownQuery =
                string.Format(
                    "SELECT * FROM Rundown_Table LEFT JOIN Vessels ON Vessels.CallSign = Rundown_Table.Call_Sign WHERE Rundown_Table.Log_ID = '{0}'",
                    logid);


            ETicketPdf ticket;
            IEnumerable<PilotTransportation> pilotTransportations = null;

            using (var cn = new OleDbConnection(ConfigurationManager.ConnectionStrings["PervasiveConnection"].ConnectionString))
            {
                cn.Open();
               // ticket = cn.Query<ETicketPdf>(PervasiveQueryString, new { Log_ID = logid }).FirstOrDefault(); // not working with Pervasive
                ticket = cn.Query<ETicketPdf>(rundownQuery).FirstOrDefault();

                if (ticket != null)
                {
                    var transportationQuery =
                        string.Format(
                            "SELECT * FROM PilotTransportation WHERE PilotCode = '{0}'",
                            ticket.Pilot_Code);

                    pilotTransportations = cn.Query<PilotTransportation>(transportationQuery);
                }

                cn.Close();
            }

            if (ticket == null)
            {
                Logger.Error("No records found for given LogId");
                return;
            }

           var pilotOptions = pilotTransportations.Select(opt => string.Format("{0} - {1}", opt.VendorID, opt.Name)).ToArray();


            var reader = new PdfReader(TemplateItextPdfPath);
            var stamper = new PdfStamper(reader, new FileStream(OutputItextPdfPath, FileMode.Open));
            //var stamper = new PdfStamper(reader, new FileStream(OutputItextPdfPath, FileMode.CreateNew, FileAccess.Write), '\0', true);
            var formFields = stamper.AcroFields;

            formFields.SetListOption("Form[0].Page1[0].VendorIdFrom1[0]", null, pilotOptions);
            formFields.SetListOption("Form[0].Page1[0].VendorIdTo1[0]", null, pilotOptions);
            formFields.SetListOption("Form[0].Page1[0].VendorIdFrom2[0]", null, pilotOptions);
            formFields.SetListOption("Form[0].Page1[0].VendorIdTo2[0]", null, pilotOptions);

            var properties = ticket.GetType().GetProperties();

            foreach (var prop in properties)
            {
                var name = prop.Name;
                var propval = prop.GetValue(ticket, null);

                if (propval != null)
                {
                    if (name == "Order_Date")
                    {
                        if(Convert.ToDateTime(propval).Year < 1902)continue;
                    }

                    formFields.SetField(name, propval.ToString());
                }

            }

            reader.RemoveUsageRights();
            stamper.Close();
            reader.Close();

            File.Copy(OutputItextPdfPath, Path.GetDirectoryName(OutputItextPdfPath) + "/" + logid + ".pdf");

            Console.WriteLine("finished");
            Console.ReadLine();
        }
    }
}

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

0
user3402190 10 Мар 2014 в 18:53

1 ответ

Лучший ответ

Ответ закомментирован в вашем собственном исходном коде.

Тебе нужно:

var stamper = new PdfStamper(reader, new FileStream(...), '\0', true);

Вместо того:

var stamper = new PdfStamper(reader, new FileStream(...));

Ваш вопрос дублирует Как правильно заполнить данные формы XFA с помощью iTextSharp, чтобы можно было редактировать и сохранять результат в Acrobat XI и более подробный ответ можно найти здесь.

Также: вы жалуетесь, что права использования удалены, но если это так, почему я вижу эту строку в вашем коде:

reader.RemoveUsageRights();

Эта строка удаляет права использования, и поэтому форма больше не может быть сохранена локально при использовании Adobe Reader.

1
Community 23 Май 2017 в 15:25
Один - это ссылка на вопрос, другой - ссылка на ответ. Нечего исправить, кроме вашего кода. Если я могу дать вам еще один совет: пожалуйста, прочтите документацию в будущем. Если вы используете метод с именем RemoveUsageRights(), спрашивать, почему права использования удаляются, будет неудобно.
 – 
Bruno Lowagie
10 Мар 2014 в 20:44
Извините, что я оставил в коде вызов прав использования. Это было для тестирования. Кроме того, я поменял местами строку кода, которую вы указали выше. Однако результат по-прежнему не работает. Если я отправлю себе исходный PDF-файл по электронной почте, я могу заполнить его, отправить и получить данные из отправленного PDF-файла. Но если я использую только что созданный PDF-файл, я получаю предупреждение от PDF Expert, в котором говорится: «Данные формы не могут быть сохранены из-за файловой структуры. Пожалуйста, повторно сохраните файл в последней версии Adobe Live Cycle Designer». Итак, с вашими изменениями что-то меняется с помощью iTextSharp. @Bruno
 – 
user3402190
10 Мар 2014 в 21:46
Кроме того ... после отправки данных из сгенерированного PDF-файла я могу видеть данные, которые пользователь заполнил в предварительном просмотре PDF-файла Outlook 2013, но не могу видеть данные, которые были предварительно заполнены. Скорее наоборот, если я открою PDF в ридере или акробате. Я могу видеть данные, которые были предварительно заполнены, но не данные, отправленные пользователем. Так что данные действительно есть в форме на некоторых уровнях, но не на уровнях дам. @Bruno Lowagie
 – 
user3402190
10 Мар 2014 в 21:50
Вы используете старую версию iText? Похоже, проблема была решена некоторое время назад.
 – 
Bruno Lowagie
10 Мар 2014 в 22:14
Вы были правы. Я использовал версию iTextSharp 4.5 ... Заменил ее на 5.5 ... Но теперь четыре раскрывающихся списка не заполняются, как раньше. formFields.SetListOption ("Form [0] .Page1 [0] .VendorIdFrom1 [0]", null, pilotOptions) больше не работает. Возможная проблема с обновлением?
 – 
user3402190
11 Мар 2014 в 00:15