Como gravar uma imagem do byte no MS WORD usando o aplicativo C # do Windows

Eu tentei gravar dados de FileStream , StreamWriter para um arquivo de palavras.

Está funcionando bem quando os dados são em formato de texto (usando o StreamWriter ). Mas quando eu tentei o mesmo com o Binarywriter (para escrever imagem para o word doc) está escrevendo incorretamente para o documento do word.

No código abaixo lstOrderedSpares[index].SparePicture é a matriz de bytes que contém os dados da imagem.

Eu preciso de uma solução sem o OPENXML.

Isso é o que eu tentei até agora:

Aqui está o meu clique do botão onde estou inicializando os dados para classs e List

  private void btnCreateQuotation_Click(object sender, EventArgs e) { try { Quotation aQuotation = new Quotation(); aQuotation.QuotationId = quotationId; aQuotation.QuotationDate = lblQuotationDateValue.Text; //Reading from Datagridview and adding to List List lstOrderedSpares = new List(); if (dataGridView1.Rows.Count > 0) { foreach (DataGridViewRow dr in dataGridView1.Rows) { Spare aSpare = new Spare(); aSpare.SapreSerialNumber = dr.Cells["SlNo"].Value.ToString(); aSpare.SparePartId = dr.Cells["SparePartID"].Value.ToString(); aSpare.SparePicture = (byte[])dr.Cells["SparePicture"].Value; aSpare.SpareDescription = dr.Cells["SpareDescription"].Value.ToString(); aSpare.EURPrice = Convert.ToDouble(dr.Cells["EURPrice"].Value.ToString()); aSpare.Quantity = Convert.ToDouble(dr.Cells["Quantity"].Value.ToString()); aSpare.TotalPrice = Convert.ToDouble(dr.Cells["TotalPrice"].Value.ToString()); aSpare.DeliveryCharge = Convert.ToDouble(txtDeliveryCharge.Text.Trim()); aSpare.Vat = txtVAT.Text.Trim(); aSpare.INRPrice = Convert.ToDouble(dr.Cells["INRPrice"].Value.ToString()); lstOrderedSpares.Add(aSpare); } } Contact aContact = new Contact(); aContact.CompanyName = txtCustomerName.Text.Trim(); aContact.ContactName = cmbContactPersonName.Text; aContact.ContactId = Convert.ToInt32(lblContactPeronIdValue.Text); aContact.CompanyId = Convert.ToInt32(lblCustomerIDValue.Text); string fileName = "SparePart_" + aQuotation.QuotationId + "_"; string fileNameWithPath = "C:\\Quotations\\SpareQuotations\\" + fileName; if (isaddedtodb) { CreateDocument(aQuotation, aContact, lstOrderedSpares, fileNameWithPath); fileNameWithPath = fileNameWithPath + aContact.CompanyName.Trim() + ".doc"; btnCreateQuotation.Visible = false; this.Hide(); //start ms word to open the document System.Diagnostics.Process.Start(fileNameWithPath); } } catch (Exception objEx) { } } 

e aqui está o método CreateDocument que grava dados no documento do Word.

  private void CreateDocument(Quotation aQuotation, Contact aContact, List lstOrderedSpares, string fileNameWithPath) { try { _Application oWord = new Microsoft.Office.Interop.Word.Application(); _Document oDoc = oWord.Documents.Add(); oWord.Visible = true; //modify secondparameter to include customer name in file name fileNameWithPath = fileNameWithPath + aContact.CompanyName.Trim() + ".doc"; //Insert text Range rng = oDoc.Range(); rng.Text = "TSV/" + aQuotation.EnquiredBy.ToString() + "/JS/" + aQuotation.QuotationId + "/SPARES" + "\t" + "\t" + "\t" + "\t" + "\t" + aQuotation.QuotationDate; //oWord.Selection.EndKey(); //oWord.Selection.TypeParagraph(); rng.InsertBreak(); rng.Text = "To ,"; rng.InsertBreak(); rng.Text = "M/s. " + aContact.CompanyName + ","; rng.InsertBreak(); rng.Text = aContact.AddressLine1 + ","; rng.InsertBreak(); rng.Text = aContact.AddressLine2 + ","; rng.InsertBreak(); rng.Text = aContact.City + "," + aContact.State + ","; rng.InsertBreak(); rng.Text = aContact.Country + "-" + aContact.PinNo; rng.InsertBreak(); rng.Text = "Phone : " + aContact.PhoneNo; rng.InsertBreak(); rng.Text = "Mobile No : " + aContact.MobileNo; rng.InsertBreak(); rng.InsertBreak(); //Salutation and subject rng.Text = "\t" + "\t" + "Kind Attention : " + aContact.ContactName; rng.InsertBreak(); rng.Text = "Dear Sir,"; rng.InsertBreak(); rng.Text = "Sub: " + aQuotation.Subject; rng.InsertBreak(); rng.Text = "Ref: your email enquiry dt: " + aQuotation.EmailEnquiredDate; rng.InsertBreak(); rng.Text = "We thank you for your valuable email enquiry dt. " + aQuotation.EmailEnquiredDate + " for supply of spares for your .........Capacity," + " fabrik nos Sl. No :.................."; rng.InsertBreak(); rng.InsertBreak(); int europeancount = 0; for (int index = 0; index < lstOrderedSpares.Count; index++) { if (lstOrderedSpares[index].INRPrice == 0.00) { europeancount++; } } rng.Text = "A) We wish to inform you that the following " + europeancount + " spares can be supplied directly by in Euros."; rng.InsertBreak(); rng.InsertBreak(); int tempslno1 = 0; for (int index = 0; index < lstOrderedSpares.Count; index++) { if (lstOrderedSpares[index].INRPrice == 0.00) { tempslno1++; rng.Text = tempslno1 + "." + lstOrderedSpares[index].SpareDescription.ToUpper() + " : ARTICLE NO: " + lstOrderedSpares[index].SparePartId + "\t" + Math.Round(lstOrderedSpares[index].EURPrice) + lblEuroSymbol.Text + "(" + new NumberToEnglish().changeCurrencyToWords(Math.Round(lstOrderedSpares[index].EURPrice)) + ")"; //To insert a picture from a byte array you need to use the Clipboard to paste it in object endOfContent = oDoc.Content.End - 1; Range rngPic = oDoc.Range(endOfContent); //Here is the trick to convert the ByteArray into an image and paste it in the document Image sparePicture = ByteArrayToImage(lstOrderedSpares[index].SparePicture); Clipboard.SetDataObject(sparePicture); rngPic.Paste(); rng.InsertBreak(); } } rng.InsertBreak(); rng.InsertBreak(); rng.Text = "Price Quoted Ex-works ."; rng.InsertBreak(); rng.Text = "Freight/Courier,Insurance,duties,any and all other expenses extra to " + "customers account."; rng.InsertBreak(); rng.InsertBreak(); rng.Text = "HOW TO ORDER :- Please register your order in favour of ...."; rng.InsertBreak(); rng.Text = "PAYMENT :- Full payment in advance against proforma invoice from ...." + " through their bankers ..... "; rng.InsertBreak(); rng.InsertBreak(); rng.Text = "Delivery / Dispatch: 2 Weeks from the date of receipt of payment."; rng.InsertBreak(); rng.Text = "In case if you have account with ...then kindly mention the account number, " + "since it will be economical if send via ...."; rng.Text = "Please provide your 'IEC Code number'."; rng.InsertBreak(); rng.InsertBreak(); rng.Text = "B) We wish to inform you that the following spare can be supplied from ex-stock " + "our Office in INR"; rng.InsertBreak(); int tempslno2 = 0; for (int index = 0; index < lstOrderedSpares.Count; index++) { if (lstOrderedSpares[index].INRPrice != 0.00) { tempslno2++; rng.Text = tempslno2 + "." + lstOrderedSpares[index].SpareDescription.ToUpper() + " : ARTICLE NO: " + lstOrderedSpares[index].SparePartId + "\t" + Math.Round(lstOrderedSpares[index].INRPrice) + " " + lblINRSymbol.Text + "(" + new NumberToEnglish().changeNumericToWords(Math.Round(lstOrderedSpares[index].INRPrice)) + ")"; //To insert a picture from a byte array you need to use the Clipboard to paste it in object endOfContent = oDoc.Content.End - 1; Range rngPic = oDoc.Range(endOfContent); //Here is the trick to convert the ByteArray into an image and paste it in the document Image sparePicture = ByteArrayToImage(lstOrderedSpares[index].SparePicture); Clipboard.SetDataObject(sparePicture); rngPic.Paste(); rng.InsertBreak(); } } rng.Text = "Price quoted ex-our office"; rng.InsertBreak(); rng.Text = "Taxes: VAT TNGST @ " + lstOrderedSpares[0].Vat + "% extra"; rng.InsertBreak(); rng.Text = "Delivery/Despatch: on receipt of order along with payment"; rng.Text = "Delivery/Courier Charges - extra " + lstOrderedSpares[0].DeliveryCharge.ToString() + "/-"; rng.InsertBreak(); rng.Text = "The order & payment may please be released in favour of..."; rng.InsertBreak(); rng.InsertBreak(); rng.Text = "Payment: Full payment in advance by way of Electronic Transfer as per following details :"; rng.InsertBreak(); rng.Text = "Current Account Number: ......"; rng.InsertBreak(); rng.Text = "IFSC Code: .........."; rng.InsertBreak(); rng.Text = "Name of the account holder: ........."; rng.InsertBreak(); rng.Text = "\t" + "\t" + "\t" + "OR"; rng.InsertBreak(); rng.Text = "By way of Demand Draft"; rng.InsertBreak(); rng.InsertBreak(); rng.Text = "Offer validity 30 days"; rng.InsertBreak(); rng.Text = "Thanking you and awaiting your valuable instructions to fulfill your needs well in time."; rng.InsertBreak(); rng.InsertBreak(); rng.Text = "Yours sincerely"; rng.InsertBreak(); oWord.Selection.EndKey(); oWord.Selection.TypeParagraph(); oDoc.SaveAs(fileNameWithPath); //If you're creating a document oDoc.Close(); oWord.Quit(); } catch (Exception objEx) { } } public Image ByteArrayToImage(byte[] byteArrayIn) { MemoryStream ms = new MemoryStream(byteArrayIn); Image returnImage = Image.FromStream(ms); returnImage = ResizeImage(returnImage, new Size(30, 30)); return returnImage; } public static Image ResizeImage(Image imgToResize, Size size) { return (Image)(new Bitmap(imgToResize, size)); } 

Quando você cria um arquivo, por exemplo, C: \ Temp \ MyWordDoc.doc e grava dados nele usando um FileStream e o StreamWriter, você está realmente gravando informações em um arquivo de texto.

A extensão de arquivo doc ou docx faz com que o Microsoft Word abra o arquivo, mas ele não está no formato do Word, é apenas texto simples.

Você precisa usar o modelo de object do MS Word para adicionar imagens em um documento do Word. Para fazer isso, faça referência a Microsoft.Office.Interop.Word .Net DLL em seu projeto e tente este código:

 using Microsoft.Office.Interop.Word; using System.IO; private void btnCreateQuotation_Click(object sender, EventArgs e) { var spareList = new List(); spareList.Add(new Spare{ SparePicture = ImageToByteArray(Image.FromFile(@"C:\temp\11.png"))}); spareList.Add(new Spare { SparePicture = ImageToByteArray(Image.FromFile(@"C:\temp\1.png")) }); CreateDocument(@"C:\Temp\MyWordDoc.docx", spareList); } public void CreateDocument(string docFilePath, List lstOrderedSpares) { Microsoft.Office.Interop.Word._Application oWord = new Microsoft.Office.Interop.Word.Application(); Microsoft.Office.Interop.Word._Document oDoc = oWord.Documents.Add(); //If you're creating a document //Microsoft.Office.Interop.Word._Document oDoc = oWord.Documents.Open(docFilePath, ReadOnly: false, Visible: true); //If you're opening a document //To see whats going on while populating the word document set Visible = true oWord.Visible = true; //Insert text Object oMissing = System.Reflection.Missing.Value; var oPara1 = oDoc.Content.Paragraphs.Add(ref oMissing); oPara1.Range.Text = "First Text"; oPara1.Range.InsertParagraphAfter(); //Here is the trick to insert a picture from a byte array into MS Word you need to //convert the ByteArray into an Image and using the Clipboard paste it into the document Image sparePicture = ByteArrayToImage(lstOrderedSpares[0].SparePicture); Clipboard.SetDataObject(sparePicture); var oPara2 = oDoc.Content.Paragraphs.Add(ref oMissing); oPara2.Range.Paste(); oPara2.Range.InsertParagraphAfter(); //Insert some more text var oPara3 = oDoc.Content.Paragraphs.Add(ref oMissing); oPara3.Range.Text = "Second Text" + Environment.NewLine; oPara3.Range.InsertParagraphAfter(); sparePicture = ByteArrayToImage(lstOrderedSpares[1].SparePicture); Clipboard.SetDataObject(sparePicture); var oPara4 = oDoc.Content.Paragraphs.Add(ref oMissing); oPara4.Range.Paste(); oPara4.Range.InsertParagraphAfter(); oDoc.SaveAs(docFilePath); //If you're creating a document //oDoc.Save(); //If you're opening a document oDoc.Close(); oWord.Quit(); } public Image ByteArrayToImage(byte[] byteArrayIn) { using (MemoryStream ms = new MemoryStream(byteArrayIn)) { Image returnImage = Image.FromStream(ms); return returnImage; } } //Method I use to test loading images from disk into byte[]'s and inserting them into word public byte[] ImageToByteArray(System.Drawing.Image imageIn) { byte[] result = null; using (MemoryStream ms = new MemoryStream()) { imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png); result = ms.ToArray(); } return result; } 

Este é o resultado:

insira a descrição da imagem aqui