"File Not found" 使用 microsoft.office.interop.word.application.documents.open() 打开时

"File Not found" when opening using microsoft.office.interop.word.application.documents.open()

我正在尝试将 docx 文件转换为 pdf。我正在使用来自 Whosebug 的代码,但经过修改以允许打开文件的动态 selection(而不是硬编码值)。当我 运行 它时,我在 Open() 方法上遇到异常 - 找不到文件。我 select 使用文件上传控件的文件,所以我知道文件在那里。怎么回事?

这是我的代码:

using System;
using System.IO;

using Microsoft.Office.Interop.Word;
using OpenXmlPowerTools;

namespace DocxToPdf
{
    public partial class WebForm1 : System.Web.UI.Page
    {

        public Microsoft.Office.Interop.Word.Document wordDoc;

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void UploadButton_Click(object sender, EventArgs e)
        {
            if (DocxFileUpload.HasFile)
            {
                string docxFile = DocxFileUpload.PostedFile.FileName;
                FileInfo fiFile = new FileInfo(docxFile);
                if (Util.IsWordprocessingML(fiFile.Extension))
                {
                    Guid pdfFileGuid = Guid.NewGuid();
                    string pdfFileLoc = string.Format(@"c:\windows\temp\{0}.pdf", pdfFileGuid.ToString());

                    Microsoft.Office.Interop.Word.Application appWord = new Microsoft.Office.Interop.Word.Application();
                    wordDoc = appWord.Documents.Open(docxFile);
                    wordDoc.ExportAsFixedFormat(pdfFileLoc, WdExportFormat.wdExportFormatPDF);
                    MsgLabel.Text = "File converted to PDF";

                }
                else
                {
                    MsgLabel.Text = "Not a WordProcessingML document.";
                }
            }
            else
            {
                MsgLabel.Text = "You have not specified a file.";

            }
        }
    }
}

错误发生在 "wordDoc = appWord.Documents.Open(docxFile);" 行。

文件上传控件 FileName 属性 只有文件名,而不是完全限定路径。我明白为什么我会收到 "file not found" 错误 - 这是因为文件中没有完全限定的路径。我对小组的问题是,我如何获得完全限定的路径和文件名,以便我可以打开它?我已经 运行 调试会话并检查了 fileupload 控件和 FileInfo 控件的所有属性,但它们没有。 FileInfo 控件的 "FullPath" 属性 设置为 "c:\Program Files (x86)\IIS Express\myfile.docx",但这不是文件所在的位置。

以下是有关该错误的更多信息:DocxToPdf.dll 中的异常 System.Runtime.InteropServices.COMException(抱歉,我们找不到您的文件。它是否可能被移动、重命名或删除?C:\ Windows...\myfile.docx...

我已经在谷歌上搜索过了,但到目前为止还没有成功。请帮忙!谢谢

首先,您应该知道 Web 应用程序有两台机器在工作——客户端(浏览器 运行s)和服务器(您的应用程序所在的位置)。每个都有自己的文件系统。服务器无法访问客户端的文件系统,反之亦然——这是出于明显的安全原因。现在也许它可以在开发机器上运行,因为您 运行 在本地创建站点,但它永远不会在生产环境中运行。

因此 Microsoft Word 无法打开位于客户端计算机上的文件。时期。客户端可以上传 文件,FileUpload 控件将允许您访问字节流——但它不会自动将文件保存在本地。您也无法访问该路径,因为该路径在客户端的文件系统上,并且他的文件夹名称是私人信息。

要使此方案完全有效,您需要先使用 FileUpload.SaveAs 将上传的文件保存在本地某处。然后您应该使用保存的文件在 Word 中打开它。像这样:

var filePath = Path.GetTempFileName();
DocxFileUpload.SaveAs(filePath);
var appWord = new Microsoft.Office.Interop.Word.Application();
var wordDoc = appWord.Documents.Open(filePath);
var convertedFilePath = Path.GetTempFileName();
wordDoc.ExportAsFixedFormat(convertedFilePath, WdExportFormat.wdExportFormatPDF);

然后您需要提供一些方法将转换后的文件返回给浏览器,by writing it to the HTTP response。示例:

Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=Converted.Pdf");
Response.AddHeader("content-type", "application/pdf");   
Response.TransmitFile(convertedFilePath);

之后不要忘记清理文件,否则随着越来越多的用户使用您的应用程序,您将 运行 磁盘空间不足 space:

}
finally
{
    File.Delete(filePath);
    File.Delete(convertedFilePath);
}

我将删除命令放在 finally 块中,这样它们 运行 即使出现问题,例如请求超时。无论如何,您都需要清理这些文件。您可能还想安排一个系统任务来每晚清理文件夹,以防其中一个文件由于 Word 挂起而被锁定,诸如此类。

此外,请确保您的应用程序的 AppPool 可以 read and write to the temp folder

如果要使用单独的处理程序进行下载

如果您想在 PDF 旁边显示其他内容,则必须使用单独的处理程序进行下载。这是一个粗略的概述:

此解决方案中使用了三个 URL:

  • Upload.aspx允许用户指定上传文件的页面
  • Confirm.asp响应显示的页面,其中包含一个大 iFrame
  • File.ashx 在 iF​​rame
  • 中显示的 returns PDF 的处理程序

您已经编码 Upload.aspx

Confirm.aspx 需要代码来接受上传、本地保存、打开 Word 和转换文件。转换文件的路径需要转换为某种标记。然后该页面需要 return 一个包含指向 File.ashx?docID=token.

的 iFrame 的页面

File.ashx 需要设置响应 headers,使用令牌重新创建 PDF 文件的路径,并通过 HttpResponse return 文件。

在某些时候,您将需要弄清楚如何清理临时文件夹,也许需要 运行 定期删除任何超过 10 分钟的 .doc 或 .pdf 文件,诸如此类的东西。