Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Tuesday, August 28, 2018 7:23 AM
Currently, I was base on "Search and replace text in a document part (Open XML SDK)" on the Microsoft site. I've realized that the code got an issue after the file has downloaded to my drive.
So I opened that file and got a message
MEMORY STREAM IS NOT EXPANDABLE at sw.Write(docText);
How to fix that?
In GenerateDocxHelper class:
private readonly MemoryStream _mem;
private Dictionary<string, string> _dicData;
public GenerateDocxHelper(string path)
{
_mem = new MemoryStream(System.IO.File.ReadAllBytes(path));
_dicData = new Dictionary<string, string>();
}
public MemoryStream ReplaceTextInWord()
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(_mem, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
foreach (var data in _dicData)
{
docText = docText.Replace(data.Key, data.Value);
}
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
_mem.Seek(0, SeekOrigin.Begin);
All replies (3)
Tuesday, August 28, 2018 11:07 AM | 1 vote
You should create MemoryStream with capacity value as 0 which means its expandable.
e.g
_mem = new MemoryStream(0);
Thanks,
Vivek Bansod
Blog | MSDN | LinkedIn
Tuesday, August 28, 2018 5:57 PM | 1 vote
You are passing an array to the MemoryStream constructor. Since you are giving it a byte array you are using the overload that uses the array as is. It won't allocate its own array and therefore you are limited to the size that the array originally has.
In general if you want to pre-populate a MemoryStream but still be able to expand it you'll use the regular constructor (not the array version) and then use Write to add the array contents.
In your code you're trying to read and write the stream. I suspect this isn't going to work out well for you. I'd also strongly recommend against storing the memory stream in a field at all since the lifetime should be the scope of the function that creates it. In your code you're opening the document with the stream and then reading all the text in. I don't really understand what your WordprocessingDocument class is providing since you keep just going back to the original stream. Nevertheless after the replacement you then try to write out to the same stream. Depending upon how your wordprocessingDocument class works this may or may not cause issues. Furthermore if something fails along the way you'll end up corrupting all your data.
I might recommend instead that you evaluate the WPD class you have to see if it adds any values. If it doesn't then the code would simplify down to a simple call to ReadAllText, foreach-replace and WriteAllText. However if this document class provides value then consider accepting the array as a parameter, creating any streams/readers you need and returning back the new array. The caller can then decide whether to store the data in the same field (if any) or whatever. Of course having duplicate arrays in memory may be inefficient for very large files but I suspect you're not having that issue here. The alternative is to accepts and return the raw stream instead. This moves the ownership of the stream to the caller and would handle arbitrary large streams of data.
Michael Taylor http://www.michaeltaylorp3.net
Wednesday, August 29, 2018 4:58 AM | 1 vote
Hi ,
>>How to fix that?
For your question,please try the code as follows.
Here is the complete code:
public void GenerateDocxHelper(string path)
{
_mem = new MemoryStream(File.ReadAllBytes(path), 0, File.ReadAllBytes(path).Length, true);
_dicData = new Dictionary<string, string>();
}
For more information , please reference:
regards,
JianGuo
MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact [email protected].