0

I'm using this tutorial https://web.archive.org/web/20211020001747/https://www.4guysfromrolla.com/articles/030211-1.aspx that’s uses a PDF template, lets the user input fields using textbox's. The file downloads onto the client’s pc but I would like to save a copy of the file into a sql database also or just save the file in the database instead of both.

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();
    }
}
2
  • It all depends on what DB you're using, but the general approach would be to store it in a "raw data" field, e.g. varbinary on SQL Server. Your question is far too broad to answer (in fact, you didn't even ask a question). Commented Sep 16, 2013 at 13:15
  • I'm sorry how would you save the file to a sql database from itextsharp? I can save a pdf to sql just can't connect the too together. Commented Sep 16, 2013 at 13:53

1 Answer 1

1

The parts of the tutorial you're looking for in that case are right here:

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

When saving a "file" to a database you essentially care about two (maybe three) things:

  • The byte array of the file contents
  • The type of the file
  • (Maybe a name for the file)

Since the tutorial concludes with two of these things (above), the type and the data, you can store these two things into your database however you need to store them. This depends on the database you're using, how you access that database, etc. Essentially to store these two things you just need a text column (varchar?) and a binary (or "blob") column (varbinary?).

The only difference is that instead of setting the type as a header in an HTTP response and writing the bytes to that HTTP response, you're using both of them as values in your database. Everything else is the same.

Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for your help, I have got the file saving to the database now but its not recording the users input.
@user2784069: At what point does it fail? It's best to update the question with the new information, including code used and indications of how that code isn't working as expected. Are you sure you're outputting the same byte array to the database which you are outputting to the user?
Hi sorry new to forums. I have edited my previous question with the code. But I think it’s this section is the problem FileStream fs = new FileStream(pdfPath, FileMode.Open, FileAccess.Read);
@user2784069: It looks like you're opening the local PDF file, populating it with data, returning the populated version to the user... then re-opening the local PDF file and saving it to the database. You need to save the version that you're returning to the user (which has the data in it) to the database, not just the local file. pdfContents should have what you want to save.
Thanks when i change pdfpath to pdf content i get the following error Compiler Error Message: CS1502: The best overloaded method match for 'System.IO.FileStream.FileStream(string, System.IO.FileMode, System.IO.FileAccess)' has some invalid arguments.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.