0

我有一些代码,希望有人可以帮助我。我想要实现的是使用嵌入的 XSLT 文件将基于 Infopaths XML 的表单转换为 Word 2007 文档以进行转换。

代码:

XPathNavigator nav = MainDataSource.CreateNavigator();
string fieldProject = nav.SelectSingleNode("//my:Project", NamespaceManager).Value;
string fieldQuote = nav.SelectSingleNode("//my:QuoteNumber", NamespaceManager).Value;
string fieldDate = nav.SelectSingleNode("//my:Date", NamespaceManager).Value;


// Define variables for the word template to use and file to create
string wordTemplateFilePath = @"\\2003server\common\OIF Proposals\TemplateFile\Interiors Letter Template.docx";
string wordPrintFilePath = @"\\2003server\common\OIF Proposals\Ben Johnson Ltd Furniture Proposal - " + fieldProject + " - " + fieldQuote + " - " + fieldDate + ".docx";

// Copy the template to create a new docx file
File.Copy(wordTemplateFilePath, wordPrintFilePath, true);

// Crack open the package
Package packWordPrint = Package.Open(wordPrintFilePath, FileMode.Open, FileAccess.ReadWrite);

// Retrieve the document.xml part of the new docx file
PackagePart part = packWordPrint.GetPart(new Uri("/word/document.xml", UriKind.Relative));

// Retrieve the xsl to use to transform the InfoPath form into document.xml
XslCompiledTransform trans = new XslCompiledTransform();
Stream xslTemplate = this.Template.OpenFileFromPackage("transform.xsl");
XmlReader xslTemplateReader = XmlReader.Create(xslTemplate);
trans.Load(xslTemplateReader);

// Create a StreamWriter to be able to write to the stream of the part
using (StreamWriter partStream = new StreamWriter(part.GetStream(FileMode.Open, FileAccess.Write)))
{
    // Transform the InfoPath form and save the XML into the stream for the part
    trans.Transform(this.MainDataSource.CreateNavigator(), null, partStream);

    // Close the stream of the part
    partStream.Close();
}

// Write changes to the package
packWordPrint.Flush();

// Close the package
packWordPrint.Close();

而且我收到大约八分之一的以下错误:

System.IO.IOException
The process cannot access the file '\\2003server\common\OIF Proposals\Ben Johnson Ltd Furniture Proposal - ABC123 - 123 - 2010-08-19.docx' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync)
   at MS.Internal.IO.Zip.ZipArchive.OpenOnFile(String path, FileMode mode, FileAccess access, FileShare share, Boolean streaming)
   at System.IO.Packaging.ZipPackage..ctor(String path, FileMode mode, FileAccess access, FileShare share, Boolean streaming)
   at System.IO.Packaging.Package.Open(String path, FileMode packageMode, FileAccess packageAccess, FileShare packageShare, Boolean streaming)
   at System.IO.Packaging.Package.Open(String path, FileMode packageMode, FileAccess packageAccess)
   at OIF_Order_Images.FormCode.CTRL31_5_Clicked(Object sender, ClickedEventArgs e)
   at Microsoft.Office.InfoPath.Internal.ButtonEventHost.OnButtonClick(DocActionEvent pEvent)
   at Microsoft.Office.Interop.InfoPath.SemiTrust._ButtonEventSink_SinkHelper.OnClick(DocActionEvent pEvent)

必须有一种明智的方法来处理或防止错误,只是无法理解它。

我想我一定不能正确地关闭某个流?

非常感谢对代码的任何指针/更改。

非常感谢

富有的

4

3 回答 3

0

最好使用它using来确保包已关闭:

using (Package packWordPrint = Package.Open(wordPrintFilePath, FileMode.Open, FileAccess.ReadWrite))
{
    ...
}

并删除该packWordPrint.Close();声明。

于 2010-08-19T16:03:24.400 回答
0

我认为问题实际上是AV。使用上述解决方案时,我仍然遇到 IOException 错误,我将继续按照它们自己的权利将它们实现为正确的,但是一旦我将写入目录放在 AV 扫描仪的异常列表中,我就停止了错误.

于 2010-08-20T07:39:02.387 回答
0

重构您的代码,使其在文件关闭时更加高效且更具确定性。这应该会有所帮助。注意:我在 SO 编辑器中进行了重新考虑,因此可能存在拼写错误、缺少大括号等。

另外,我不确定您还在使用 packWordPrint 做什么,但它真的需要打开 ReadWrite 吗?看起来你只是从中读取,所以打开它 ReadOnly 会更聪明,你不需要在最后调用 Flush。

XPathNavigator nav = MainDataSource.CreateNavigator();
string fieldProject = nav.SelectSingleNode("//my:Project", NamespaceManager).Value;
string fieldQuote = nav.SelectSingleNode("//my:QuoteNumber", NamespaceManager).Value;
string fieldDate = nav.SelectSingleNode("//my:Date", NamespaceManager).Value;

// Retrieve the xsl to use to transform the InfoPath form into document.xml
Stream xslTemplate = this.Template.OpenFileFromPackage("transform.xsl");
XmlReader xslTemplateReader = XmlReader.Create(xslTemplate);

XslCompiledTransform trans = new XslCompiledTransform();
trans.Load(xslTemplateReader);

// Define variables for the word template to use and file to create
string wordTemplateFilePath = @"\\2003server\common\OIF Proposals\TemplateFile\Interiors Letter Template.docx";
string wordPrintFilePath = string.Format(@"\\2003server\common\OIF Proposals\Ben Johnson Ltd Furniture Proposal - {0} - {1} - {2}.docx",fieldProject, fieldQuote,fieldDate);

// Copy the template to create a new docx file
File.Copy(wordTemplateFilePath, wordPrintFilePath, true);

// Crack open the package
using (Package packWordPrint = Package.Open(wordPrintFilePath, FileMode.Open, FileAccess.ReadWrite))
{

  // Retrieve the document.xml part of the new docx file
  PackagePart part = packWordPrint.GetPart(new Uri("/word/document.xml", UriKind.Relative));

  // Create a StreamWriter to be able to write to the stream of the part
  using (StreamWriter partStream = new StreamWriter(part.GetStream(FileMode.Open, FileAccess.Write)))
  {
      // Transform the InfoPath form and save the XML into the stream for the part
      trans.Transform(this.MainDataSource.CreateNavigator(), null, partStream);
  }

  // Write changes to the package
  packWordPrint.Flush();

}
于 2010-08-19T17:02:11.200 回答