Search code examples
pdfoffice-interopfilestreamvarbinary

read word document from varbinary, edit, create a write protected pdf


I have a method that uses Microsoft.Office.Interop to read a Word document, edit it, and write it as a PDF. I have a separate method that uses Itext7 to read this PDF and write it to a different PDF that can be viewed and printed, but cannot be easily altered.

The first method reads the word document from disk; however, I've been asked to make it read the document from an sql query from a variable stored as varbinary and write the final result as a varbinary -without using any intermediate files on disk. I think I need to read these as "streams"

Here's what I have:

class clsMakeCert
{
    string myName;
    public string myDate;

    public clsMakeCert(string name, DateTime date)
    {
        myName = name;
        myDate = date.ToString("MM/dd/yyyy");
    }
    public void createCertPdf(string certFilename)
    {
        // Get the document out of the SQL table
        System.Data.DataTable dtContents = new System.Data.DataTable();
        SqlDataReader rdr_Contents = null;

        using (SqlConnection conn = new SqlConnection("Server=KGREEN3-LT\\SQLEXPRESS;Initial Catalog=SAN;Integrated Security=SSPI"))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand("Select [file_data] From cert_files where filename=@certFilename", conn);
            {
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.AddWithValue("@certFilename", certFilename);
                rdr_Contents = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                dtContents.Load(rdr_Contents);
            }
        }
        byte[] byteArray = (byte[])dtContents.Rows[0]["file_data"];

        // Put it into a word document
        Application wordApp = new Application { Visible = false };
        Document doc = new Document();

        using (MemoryStream stream = new MemoryStream())
        {
            stream.Write(byteArray, 0, (int)byteArray.Length);
            doc = wordApp.Documents.Open(stream, ReadOnly: false, Visible: false);
            doc.Activate();
            FindAndReplace(wordApp, "First Middle Last", myName);
            FindAndReplace(wordApp, "11/11/1111", myDate);

        }



        return ;

    }

}

It doesn't look like the open method will accept a stream, though.

It looks like I can use openXML to read / edit the docx as a stream. But it won't convert to pdf. It looks like I can use Interop to read /edit the docx AND write to PDF, but I can't do it as a stream (only as a file on disk).

Is there a way to get Interop to read a stream (i.e. a file loaded from a varbinary)? k


Solution

  • No, the Word "Interop" does not support streaming. The closest it comes (and it's the only Office application that has this capability) is to pass in the necessary Word Open XML in the OPC flat file format using the obejct model's InsertXML method. It's not guaranteed, however, that the result will be an exact duplicate of the Word Open XML file being passed in as the target document's settings could override some of the in-coming settings.