0
Guys, I’m doing a job RESTFUL in C# that has a method that receives a byte array of a document WORD, and in this document I need to replace existing bookmarks with text that are also passed in the method.
Problem : When performing the replacement of bookmarks by the appropriate text I cannot update the Memorystream to obtain the byte array updated with file modifications. Someone has already had to work with
Referential
public class ReferenciaRelatorio { public string referencia {get; set;} public object valor { get; set; } }
Reporteriods
[DataContract] public class RelatorioDS { [DataMember] public List<ReferenciaRelatorio> mapaDeSubstituicao { get; set; } /**arquivo binario na base 64**/ [DataMember] public string template { get; set; } }
Geradorrelatorioword (EDITED)
using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Web; using Microsoft.Office.Interop.Word; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wordprocessing; using DocumentFormat.OpenXml; namespace RestService { public class GeradorRelatorioWord { public ResponseData gerarRelatorio(RelatorioDS data) { ResponseData resposta = new ResponseData(); try { byte[] saida = null; byte[] template = System.Convert.FromBase64String(data.template); using (MemoryStream mem = new MemoryStream(template)) { /**EDITADO**/ /**mem.Write(template, 0, (int)template.Length);**/ using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(mem, false)) { var bookMarks = recuperarBookMark(wordDoc.MainDocumentPart.Document); substituirBookMark(data, bookMarks); byte[] buf; Stream stream = wordDoc.MainDocumentPart.GetStream(); buf = new byte[stream.Length]; stream.Read(buf, 0, buf.Length); saida = buf ; /** EDITADO **/ /** wordDoc.MainDocumentPart.Document.Save(); wordDoc.Close(); using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream())) { string documentoTexto = sr.ReadToEnd(); using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create))) { sw.Write(documentoTexto); MemoryStream me = new MemoryStream(); sw.BaseStream.CopyTo(me); saida = me.ToArray(); } }**/ } resposta.relatorio = System.Convert.ToBase64String(saida); } } catch(Exception e) { resposta.erros.Add(new MensagemErro(e)); } return resposta; } /** * Recupera os BookMarks que existirem **/ private Dictionary<string, BookmarkEnd> recuperarBookMark(OpenXmlElement documentPart, Dictionary<string, BookmarkEnd> results = null, Dictionary<string, string> unmatched = null) { results = results ?? new Dictionary<string, BookmarkEnd>(); unmatched = unmatched ?? new Dictionary<string, string>(); foreach (var child in documentPart.Elements()) { if (child is BookmarkStart) { var bStart = child as BookmarkStart; unmatched.Add(bStart.Id, bStart.Name); } if (child is BookmarkEnd) { var bEnd = child as BookmarkEnd; foreach (var orphanName in unmatched) { if (bEnd.Id == orphanName.Key) results.Add(orphanName.Value, bEnd); } } recuperarBookMark(child, results, unmatched); } return results; } /** * substitui os bookmarks * * **/ private static void substituirBookMark(RelatorioDS data, Dictionary<string, BookmarkEnd> bookMarks) { foreach (var end in bookMarks) { string bookmark = Uri.UnescapeDataString(end.Key); foreach (ReferenciaRelatorio entry in data.mapaDeSubstituicao) { if (bookmark.Equals(entry.referencia)) { var textElement = new Text((string)entry.valor); var runElement = new Run(textElement); end.Value.InsertAfterSelf(runElement); } } } } } }
thanks for the tips. Just a doubt,I think the Stream class does not have the Toarray method. I made the changes to your answer, however the file I get from byte array it gets corrupted. @carlosfigueira
– Diogo Calazans
Ah, this is a Extension method that I have in my library. You can copy to a memory stream using the
CopyTo
then.– carlosfigueira