0

ページあたり 60 ラベルの PDF テンプレート ファイルがあります。私の目標は、必要に応じてテンプレートのコピーを作成し、フォーム データを入力してから、ファイルを 1 つの PDF にマージすること (または個々のファイルへのリンクを提供すること) でした。

問題は、日付に関係なく、2 番目の PDF コピーが破損していることです。

ワークフローは、ユーザーが日付を選択することです。その日の昼食の注文は、テンプレートのフォーム フィールドへの入力に使用される一般的なリストにまとめられます。60 で、ファイルは一時ファイルとして保存され、テンプレートの新しいコピーが次の 60 の名前に使用されます。

2013 年 9 月 23 日から 9 月 25 日までのデータがあります。25 日に 38 の注文しかないため、これは意図したとおりに機能します。2013 年 9 月 24 日に 60 件以上の注文があり、最初のページは機能しますが、2 ページ目は破損しています。

    private List<string> CreateLabels(DateTime orderDate)
{

    // create file name to save
    string fName = ConvertDateToStringName(orderDate) + ".pdf"; // example 09242013.pdf

    // to hold Temp File Names
    List<string> tempFNames = new List<string>(); 

    // Get path to template/save directory
    string path = Server.MapPath("~/admin/labels/");
    string pdfPath = path + "8195a.pdf"; // template file

    // Get the students and their lunch orders
    List<StudentLabel> labels = DalStudentLabel.GetStudentLabels(orderDate);


    // Get number of template pages needed
    decimal recCount = Convert.ToDecimal(labels.Count);
    decimal pages = Decimal.Divide(recCount, 60);
    int pagesNeeded = Convert.ToInt32(Math.Ceiling(pages));


    // Make the temp names
    for (int c = 0; c < pagesNeeded; c++)
    {
        tempFNames.Add(c.ToString() + fName); //just prepend a digit to the date string
    }

    //Create copies of the empty templates
    foreach (string tName in tempFNames)
    {
        try
        { File.Delete(path + tName); }
        catch { }

        File.Copy(pdfPath, path + tName);
    }

    // we know we need X pages and there is 60 per page
    int x = 0;

    // foreach page needed
    for (int pCount = 0; pCount < pagesNeeded; pCount++)
    {
        // Make a new page
        PdfReader newReader = new PdfReader(pdfPath);

        // pCount.ToString replicates temp names
        using (FileStream stream = new FileStream(path + pCount.ToString() + fName, FileMode.Open))
        {
            PdfStamper stamper = new PdfStamper(newReader, stream); 

            var form = stamper.AcroFields;
            var fieldKeys = form.Fields.Keys;

            StudentLabel lbl = null;

            string lblInfo = "";

            // fill in acro fields with lunch data
            foreach (string fieldKey in fieldKeys)
            {
                try
                {
                    lbl = labels[x];
                }
                catch 
                { 
                    break; 
                } // if we're out of labels, then we're done

                lblInfo = lbl.StudentName + "\n";
                lblInfo += lbl.Teacher + "\n";
                lblInfo += lbl.MenuItem;

                form.SetField(fieldKey, lblInfo);

                x++;

                if (x % 60 == 0)  // reached 60, time for new page
                {
                    break;
                }
            }

            stamper.Writer.CloseStream = false;
            stamper.FormFlattening = true;
            stamper.Close();
            newReader.Close();

            stream.Flush();
            stream.Close();
        }        
    }

    return tempFNames;
}
4

1 に答える 1

1

ファイルを事前に割り当てているのはなぜですか? 私の推測では、それはあなたの問題です。PdfStamperaPdfReaderを入力用にバインドし、同じ pdf の正確なコピーFileStreamを出力用のオブジェクトにバインドしています。PdfStamperが出力ファイルを生成してくれるので、手伝う必要はありません。新しいデータを既存のファイルに追加しようとしていますが、その場合に何が起こるかはよくわかりません (実際に誰かがそれを行うのを見たことがないため)。

したがって、File.Copy事前割り当て全体を削除し、FileStream宣言を次のように変更します。

using (FileStream stream = new FileStream(path + pCount.ToString() + fName, FileMode.Create, FileAccess.Write, FileShare.None))

明らかに、戻り値の配列がどのように取り込まれるかを調整する必要もあります。

于 2013-09-25T13:06:46.953 に答える