2017-06-19 49 views
0

打開時出現「文件未找到」我試圖將docx文件轉換爲pdf。我使用的是來自stackoverflow的代碼,但經過修改後允許動態選擇要打開的文件(而不是硬編碼的值)。當我運行它時,我在Open()方法上得到一個異常 - 找不到文件。我使用fileupload控件選擇文件,所以我知道該文件在那裏。這是怎麼回事?當使用microsoft.office.interop.word.application.documents.open()

這是我的代碼:

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中的異常System.Runtime.InteropServices.COMException(對不起,我們無法找到您的文件,它可能被移動,重命名或刪除了嗎?C:\ Windows ... \ myfile.docx ...

我已經在這周圍一派,但至今沒有運氣。請幫助!謝謝。

+0

問題在於如何設置DocxFileUpload.PostedFile.FileName。沒有這個代碼,不能真正幫助 – bnem

回答

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塊,以便它們即使出現問題時也會運行,例如請求超時。無論如何,你都需要這些文件來清理。您可能還想安排一個系統任務來每晚清理文件夾,以防萬一某個文件被掛起而導致文件被掛起等情況。

此外,請確保您的應用程序的AppPool可以read and write to the temp folder

如果你想使用一個單獨的處理程序下載

如果你想顯示其它內容的PDF旁邊,你必須使用一個單獨的處理程序進行下載。這裏有一個大致的輪廓:

有在這個解決方案中使用三個URL:

  • 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文件,諸如此類的事情。

+0

你提供的一行代碼令我費解:var wordDoc = appWord.Documents.Open(docxFile);'。括號中的值不應該是「filePath」嗎?該變量包含保存文件的標準路徑和文件名。 「DocxFile」只是文件名。 Open()方法如何找到文件? –

+0

你是對的。我編輯了我的帖子。 –

+0

是否有必要創建一個HTTP處理程序,就像在您提供的鏈接中完成的那樣?或者可以將上面的代碼直接放入我當前的asp頁面中?我的下一步是在屏幕上顯示PDF文件,並帶有「保存」按鈕。點擊它將它保存到數據庫。一旦文件在Response對象中,它會停留在那裏還是會被覆蓋? –