c# Microsoft.Office.Interop.Word.Document to Stream - c#

I have a active document :
Microsoft.Office.Interop.Word.Document document = Globals.ThisAddIn.Application.ActiveDocument;
How I can convert this to stream?
Or even better, how to send active document to rest web service?
Thanks

Which rest-service? If it's SharePoint or the like i'm used to just calling the SaveAs function as follows:
Microsoft.Office.Interop.Word.Document document = Globals.ThisAddIn.Application.ActiveDocument;
document.SaveAs("https://www.contoso.sharepoint.com/Documents/Document1.docx");
Edit: P.S. You can serialize anything to Stream.
found an answer here
public static MemoryStream SerializeToStream(object o)
{
MemoryStream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, o);
return stream;
}
public static object DeserializeFromStream(MemoryStream stream)
{
IFormatter formatter = new BinaryFormatter();
stream.Seek(0, SeekOrigin.Begin);
object o = formatter.Deserialize(stream);
return o;
}

Save to a temp file then read file content as required by the rest service, e.g. byte array. Or use Open XML SDK if older Word formats are not required.

Related

.Net C# DocX librairy : how to serialize a DocX document?

When using the DocX librairy, i am generating the docx document on server then download it.
For that, i need to convert my document in an array of bytes.
To do that, i was previousloy saving the document as a physical file like this :
// Save all changes to this document.
document.SaveAs(GENERATED_DOCX_LOCATION);
return System.IO.File.ReadAllBytes(GENERATED_DOCX_LOCATION);
but i would rather not do that. Is it possible to serialize this object to download it without saving it physically ?
I already tried that :
private byte[] ObjectToByteArray(object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
With :
return this.ObjectToByteArray(document);
But obviously, DocX doesn't implement ISerializable.
EDIT : the code below doesn't work either
byte[] byteArray = null;
using (var stream = new MemoryStream())
{
document.SaveAs(stream);
byteArray = stream.ToArray();
}
return byteArray;
Try this, replace my c:\temp... path with your document location and this will get and write the file for you from the byte array
void Main()
{
byte[] bytes = System.IO.File.ReadAllBytes(#"C:\temp\test.csv");
using (var bw = new BinaryWriter(File.Open(#"C:\temp\test2.csv", FileMode.OpenOrCreate)))
{
bw.Write(bytes);
bw.Flush();
}
}
There was no way to do it via the original DocX library.
It's a shame as this library uses a MemoryStream to manupulate the datas.
To solve my problem i simply added a new public readonly property to expose the private MemoryStream variable, then i used this simple code :
Code added in the DocX project :
public MemoryStream DocumentMemoryStream { get { return this.memoryStream; } }
Code in my main function :
return document.DocumentMemoryStream.ToArray();

Worksbook saved with stream is broken

recently I was trying to save Aspose.Cells.Workbook to stream with
private Stream GetWorkbook()
{
// processing workbook here
// ...
// saving to stream
return workbook.SaveToStream();
}
private void Save()
{
using (stream = GetWorkbook())
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
stream.CopyTo(fileStream);
}
}
But when I'm trying to open generated .xlsx file Excel sends me an error that file is corrupted.
SaveToStream() method will only save your workbook in XLS format. So you should not use this method but use the following code to save your workbook in memory stream object. It should fix your issue.
C#
//Load your Excel file
Workbook wb = new Workbook(yourFile);
//Create memory stream object
MemoryStream ms = new MemoryStream();
//Determine the save format
SaveFormat svfmt = (SaveFormat)wb.FileFormat;
//Save the workbook to memory stream
wb.Save(ms, svfmt);
Note: I am working as Developer Evangelist at Aspose

write to csv file gets cut when writing using file.writeallbytes

I am trying to read a CSV file and storing it in object.
I then write the object into a file using bytes
File.WriteAllBytes("some.csv",ObjectToByteArray(items));
private byte[] ObjectToByteArray(Object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
return encoding.GetBytes(ms.ToString());
}
The file doesnt get written completely and it gets cut. I sense this is due to stream size restrictions.
How to ensure the entire file is being written correctly. When I use CSVwriter it still doesnt seem to work.

unable to save dynamically created MemoryStream with rebex sftp

I'm using StreamWriter to generate a dynamic file and holding it in a MemoryStream. Everything appears to be alright until I go to save the file using rebex sftp.
The example they give on their site works fine:
// upload a text using a MemoryStream
string message = "Hello from Rebex FTP for .NET!";
byte[] data = System.Text.Encoding.Default.GetBytes(message);
System.IO.MemoryStream ms = new System.IO.MemoryStream(data);
client.PutFile(ms, "message.txt");
However the code below does not:
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream))
{
writer.AutoFlush = true;
writer.Write("test");
}
client.PutFile(stream, "test.txt");
}
The file "test.txt" is saved, however it is empty. Do I need to do more than just enable AutoFlush for this to work?
After writing to the MemoryStream, the stream is positioned at the end. The PutFile method reads from the current position to the end. That's exactly 0 bytes.
You need to position the stream at the beginning before passing it to PutFile:
...
}
stream.Seek(0, SeekOrigin.Begin);
client.PutFile(stream, "test.txt");
You may also need to prevent the StreamWriter from disposing the MemoryStream:
var writer = new StreamWriter(stream);
writer.Write("test");
writer.Flush();
stream.Seek(0, SeekOrigin.Begin);
client.PutFile(stream, "test.txt");

Loading binary file from db and process it as openxml

I have such method to load document file from db that is stored as binary and then replace customxml parts with parameters.
Somehow when i convert byte into MemoryStream then process it doesn't work, my custom xml parts are not replaced. But if i use FileStream and read same file from disk then it replaced perfectly!
What is wrong with MemoryStream? i can't also cast MemoryStream to FileStream or create instrance of Stream or etc..
Any suggestion?
private static Stream LoadContent(byte[] content, XmlDocument parameters)
{
//FileStream works perfectly
//Stream fileStream = new FileStream(#"C:\temp\test.docx", FileMode.Open);
Stream documentStream = new MemoryStream();
documentStream.Write(content, 0, content.Length);
//Processes word file, replace custom xml parts with parameters
using (WordprocessingDocument document = WordprocessingDocument.Open(documentStream, true))
{
MainDocumentPart mainPart = document.MainDocumentPart;
Stream partStream = mainPart.CustomXmlParts.First().GetStream();
using (XmlWriter xmlWriter = XmlWriter.Create(partStream, new XmlWriterSettings { CloseOutput = false }))
{
parameters.WriteTo(xmlWriter);
xmlWriter.Flush();
}
mainPart.Document.Save();
}
return documentStream;
}
You might want to try to set the 'Position' propery of the memorystream to 0 after writing data to it and before reading it again.
Alernatively you can also pass the byte array to the constructor of the memorystream instead of calling writer.
edit
I see according to MSDN that the 'Document.Save' method will flush the stream to allow propper saving. ( http://msdn.microsoft.com/en-us/library/cc840441.aspx ).
However MemoryStream wont do anything on flush ( http://msdn.microsoft.com/en-us/library/system.io.memorystream.flush.aspx ).
You could try to create a new MemoryStream and then pass that as a parameter to the 'Document.Save' method.

Categories