流式传输到包中,打包到 WordDocument 中,然后再返回

发布于 2024-11-25 13:07:47 字数 1216 浏览 0 评论 0原文

我不了解 Streams 的所有机制,更不了解 System.IO.Package 类的机制。

我有一个 .docx 文档作为数据库中的二进制文件,我不想获取它,进行一些修改,然后保存它。

我目前有在单独的库中修改文档的方法,因为它将在很多地方使用。

这就是我尝试执行此操作的方式:

byte[] doc = getDocFromDB();
using (MemoryStream mem = new MemoryStream())
{
    mem.Write(doc, 0, doc.Length);

    Package pack = Package.Open(mem, FileMode.Open, FileAccess.ReadWrite);
    filler.FillTemplate(ref pack, someIrreleventData);

    string filePath = Path.GetTempPath() + "docname.docx";

    using (FileStream file = new FileStream(filePath, FileMode.Create))
    {
        mem.WriteTo(file);
        file.Flush();
        file.Close();
    }

    Process.Start(filePath);
}

库代码如下所示:

public void FillTemplate(ref Package package, XElement data)
{
    WordprocessingDocument document = WordprocessingDocument.Open(package);

    //add the data to the document

    //should I do document.close() or document.dispose() here?

}

文档就像保存到数据库中一样出来,没有添加所有额外的数据。

我假设我用内存流打开包对包的所有更改也将保存到流中。

我做错了什么以及我怎样才能做得更好。

编辑

我错了,我的代码没有任何问题。问题是 someIrreleventData 部分为 null,并且那里的 fetcher 和 FillTemplate 方法内的代码都没有正确处理异常。

I do not understand all the mechanics surrounding Streams and even less around the System.IO.Package class.

I have a .docx document as a binary in a DataBase and I wan't to fetch it, modify somewhat and then save it.

I currently have the method that modifies the document in a seperate library because it will be used in many places.

This is how I tried to do this:

byte[] doc = getDocFromDB();
using (MemoryStream mem = new MemoryStream())
{
    mem.Write(doc, 0, doc.Length);

    Package pack = Package.Open(mem, FileMode.Open, FileAccess.ReadWrite);
    filler.FillTemplate(ref pack, someIrreleventData);

    string filePath = Path.GetTempPath() + "docname.docx";

    using (FileStream file = new FileStream(filePath, FileMode.Create))
    {
        mem.WriteTo(file);
        file.Flush();
        file.Close();
    }

    Process.Start(filePath);
}

With the library code going something like this:

public void FillTemplate(ref Package package, XElement data)
{
    WordprocessingDocument document = WordprocessingDocument.Open(package);

    //add the data to the document

    //should I do document.close() or document.dispose() here?

}

The document just comes out just as it was saved into the DB without all the extra data added in.

I assumed as I opened the Package with a memory stream all the changes to the package would be saved into the stream as well.

What am I doing wrong and how can I do it better.

EDIT

I was wrong, there isn't anything broken with my code. Problem was that someIrreleventData part was null and both the fetcher there and the code inside FillTemplate method didn't handle the exception correctly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我没有看到您在尝试将包保存到文件之前调用 Flush() 和/或 Close() 的地方...
尝试更改

mem.Write(doc, 0, doc.Length);

mem.Position = 0; // new, perhaps this is relevant for Package.Open ?

Package pack = Package.Open(mem, FileMode.Open, FileAccess.ReadWrite);
filler.FillTemplate(ref pack, someIrreleventData);

pack.Flush(); pack.Close(); // new
mem.Position = 0;  // new

AND:是的,您应该调用 document.Close()

调用 .Dispose() 是一个好主意,但如果您使用 using 块来处理这个问题和其他一些事情,那就更好了......

I don't see any place where you call Flush() and/or Close() on the Package before trying to save it to file...
try changing

mem.Write(doc, 0, doc.Length);

mem.Position = 0; // new, perhaps this is relevant for Package.Open ?

Package pack = Package.Open(mem, FileMode.Open, FileAccess.ReadWrite);
filler.FillTemplate(ref pack, someIrreleventData);

pack.Flush(); pack.Close(); // new
mem.Position = 0;  // new

AND: yes, you should call document.Close() .

Calling .Dispose() is a good idea though it would even be better if you used as using block which takes care of that and several other things...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文