使用microsoft.office.interop.word.application.documents.open()

时间:2017-06-19 19:34:03

标签: c# asp.net file-upload office-interop

我正在尝试将docx文件转换为pdf。我正在使用stackoverflow中的代码,但已修改为允许动态选择要打开的文件(而不是硬编码值)。当我运行它时,我在Open()方法上得到一个例外 - 找不到文件。我使用fileupload控件选择文件,所以我知道文件在那里。发生了什么事?

这是我的代码:

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);”上发生错误线。

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

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

我已经搜索过这个,但到目前为止还没有运气。请帮忙!感谢。

1 个答案:

答案 0 :(得分:1)

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

因此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);

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

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

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

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

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

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

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

  • Upload.aspx允许用户指定要上传的文件的页面
  • Confirm.asp响应中显示的页面,其中包含大型iFrame
  • File.ashx返回iFrame
  • 中显示的PDF的处理程序

您已编码Upload.aspx

Confirm.aspx需要代码来接受上传,本地保存,打开Word以及转换文件。转换后的文件的路径需要转换为某种令牌。然后,该页面需要返回包含指向File.ashx?docID=token的iFrame的页面。

File.ashx需要设置响应标头,使用标记重新创建PDF文件的路径,并通过HttpResponse返回文件。

在某些时候,你需要弄清楚如何清理临时文件夹,可能是一个定期运行的作业,并删除任何超过10分钟的.doc或.pdf文件,等等。