0

我正在使用本教程http://www.4guysfromrolla.com/articles/030211-1.aspx,它使用 PDF 模板,让用户使用文本框输入字段。文件下载到客户端的电脑上,但我想将文件的副本保存到 sql 数据库中,或者只是将文件保存在数据库中,而不是两者都保存。

protected void btnGeneratePDF_Click(object sender, EventArgs e)
{
    var pdfPath = Path.Combine(Server.MapPath("~/PDFTemplates/fw9.pdf"));

    // Get the form fields for this PDF and fill them in!
    var formFieldMap = PDFHelper.GetFormFieldNames(pdfPath);
    formFieldMap["topmostSubform[0].Page1[0].f1_01_0_[0]"] = txtName.Text;
    formFieldMap["topmostSubform[0].Page1[0].f1_02_0_[0]"] = txtBusinessName.Text;

    if (rblTaxClassification.SelectedValue != null)
    {
        var formFieldName = string.Format("topmostSubform[0].Page1[0].c1_01[{0}]", rblTaxClassification.SelectedIndex);
        formFieldMap[formFieldName] = (rblTaxClassification.SelectedIndex + 1).ToString();
    }

    if (chkExemptPayee.Checked)
        formFieldMap["topmostSubform[0].Page1[0].c1_01[7]"] = "8";
        

    formFieldMap["topmostSubform[0].Page1[0].f1_04_0_[0]"] = txtAddress.Text;
    formFieldMap["topmostSubform[0].Page1[0].f1_05_0_[0]"] = txtCityStateZIP.Text;
    formFieldMap["topmostSubform[0].Page1[0].f1_07_0_[0]"] = txtAccountNumbers.Text;

    // Requester's name and address (hard-coded)
    formFieldMap["topmostSubform[0].Page1[0].f1_06_0_[0]"] = "Acme Website\n123 Anywhere Lane\nSpringfield, USA";

    // SSN
    if (!string.IsNullOrEmpty(txtSSN1.Text))
    {
        formFieldMap["topmostSubform[0].Page1[0].social[0].TextField1[0]"] = txtSSN1.Text;
        formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[0]"] = txtSSN2.Text;
        formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[1]"] = txtSSN3.Text;
    }
    else if (!string.IsNullOrEmpty(txtEIN1.Text))
    {
        formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[2]"] = txtEIN1.Text;
        formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[3]"] = txtEIN2.Text;
    }

    var pdfContents = PDFHelper.GeneratePDF(pdfPath, formFieldMap);

    PDFHelper.ReturnPDF(pdfContents, "Completed-W9.pdf");

    FileStream fs = new FileStream(pdfPath, FileMode.Open, FileAccess.Read);
    BinaryReader br = new BinaryReader(fs);
    Byte[] bytes = br.ReadBytes((Int32)fs.Length);
    br.Close();
    fs.Close();

    //insert the file into database
    string strQuery = "insert into tblFiles(Name, ContentType, Data) values (@Name, @ContentType, @Data)";
    SqlCommand cmd = new SqlCommand(strQuery);
    cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Completed-W9132.pdf";
    cmd.Parameters.Add("@ContentType", SqlDbType.VarChar).Value = "application/pdf";
    cmd.Parameters.Add("@Data", SqlDbType.Binary).Value = bytes;
    InsertUpdateData(cmd);

App_code/pdfHelper.cs

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Web;
using System.IO;
using iTextSharp.text.pdf;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;  

public class PDFHelper
{
    public static Dictionary<string, string> GetFormFieldNames(string pdfPath)
    {
        var fields = new Dictionary<string, string>();

        var reader = new PdfReader(pdfPath);
        foreach (DictionaryEntry entry in reader.AcroFields.Fields)
            fields.Add(entry.Key.ToString(), string.Empty);
        reader.Close();

        return fields;
    }

    public static byte[] GeneratePDF(string pdfPath, Dictionary<string, string> formFieldMap)
    {
        var output = new MemoryStream();
        var reader = new PdfReader(pdfPath);
        var stamper = new PdfStamper(reader, output);
        var formFields = stamper.AcroFields;

        foreach (var fieldName in formFieldMap.Keys)
            formFields.SetField(fieldName, formFieldMap[fieldName]);

        stamper.FormFlattening = true;
        stamper.Close();
        reader.Close();

        return output.ToArray();
    }

    // See http://stackoverflow.com/questions/4491156/get-the-export-value-of-a-checkbox-using-itextsharp/
    public static string GetExportValue(AcroFields.Item item)
    {
        var valueDict = item.GetValue(0);
        var appearanceDict = valueDict.GetAsDict(PdfName.AP);

        if (appearanceDict != null)
        {
            var normalAppearances = appearanceDict.GetAsDict(PdfName.N);
            // /D is for the "down" appearances.

            // if there are normal appearances, one key will be "Off", and the other
            // will be the export value... there should only be two.
            if (normalAppearances != null)
            {
                foreach (var curKey in normalAppearances.Keys)
                    if (!PdfName.OFF.Equals(curKey))
                        return curKey.ToString().Substring(1); // string will have a leading '/' character, so remove it!
            }
        }

        // if that doesn't work, there might be an /AS key, whose value is a name with 
        // the export value, again with a leading '/', so remove it!
        var curVal = valueDict.GetAsName(PdfName.AS);
        if (curVal != null)
            return curVal.ToString().Substring(1);
        else
            return string.Empty;
    }

    public static void ReturnPDF(byte[] contents)
    {
        ReturnPDF(contents, null);
    }

    public static void ReturnPDF(byte[] contents, string attachmentFilename)
    {
        var response = HttpContext.Current.Response;

        if (!string.IsNullOrEmpty(attachmentFilename))
            response.AddHeader("Content-Disposition", "attachment; filename=" + attachmentFilename);

        response.ContentType = "application/pdf";
        response.BinaryWrite(contents);
          response.End();
    }
}
4

1 回答 1

1

在这种情况下,您正在寻找的教程部分就在这里:

Response.ContentType = "application/pdf";
Response.BinaryWrite(output.ToArray());

将“文件”保存到数据库时,您基本上关心两(也许三)件事:

  • 文件内容的字节数组
  • 文件类型
  • (可能是文件名)

由于本教程以其中两件事(上图)结束,即类型和数据,您可以将这两件事存储到您的数据库中,但是您需要存储它们。这取决于您使用的数据库、访问该数据库的方式等。基本上要存储这两个内容,您只需要一个文本列(varchar?)和一个二进制(或“blob”)列(varbinary?)。

唯一的区别是,您不是将类型设置为 HTTP 响应中的标头并将字节写入该 HTTP 响应,而是将它们都用作数据库中的值。其他一切都是一样的。

于 2013-09-16T13:17:08.703 回答