2017-06-19 1 views
0

Je suis en train de convertir un fichier docx en fichier pdf. J'utilise le code de stackoverflow, mais modifié pour permettre la sélection dynamique d'un fichier à ouvrir (plutôt que d'une valeur codée en dur). Lorsque je l'exécute, j'obtiens une exception sur la méthode Open() - impossible de trouver le fichier. Je sélectionne le fichier en utilisant un contrôle fileupload donc je sais que le fichier est là. Que se passe-t-il?"Fichier introuvable" lors de l'ouverture à l'aide de microsoft.office.interop.word.application.documents.open()

Voici mon code:

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."; 

      } 
     } 
    } 
} 

L'erreur se produit sur la "WordDoc = appWord.Documents.Open (docxFile);" ligne.

La propriété fileupload control FileName a juste le nom du fichier, pas le chemin qualifié complet. Je comprends pourquoi j'obtiens une erreur «fichier non trouvé» - c'est parce que le fichier ne contient pas le chemin qualifié complet. Ma question au groupe est la suivante: comment puis-je obtenir le chemin complet et le nom de fichier, afin que je puisse l'ouvrir? J'ai exécuté une session de débogage et examiné toutes les propriétés du contrôle fileupload et le contrôle FileInfo, mais ils ne l'ont pas. La propriété "FullPath" du contrôle FileInfo est définie sur "c: \ Program Files (x86) \ IIS Express \ monfichier.docx", mais ce n'est pas l'emplacement du fichier.

Voici de plus amples informations sur l'erreur: Exception System.Runtime.InteropServices.COMException dans DocxToPdf.dll (Désolé, nous n'avons pas trouvé votre fichier Est-il possible qu'il soit déplacé, renommé ou supprimé? C: \ Windows ... \ myfile.docx ...

J'ai googlé autour de ce sujet, mais aucune chance. S'il vous plaît aider! Merci.

+0

Le problème réside dans la façon dont 'DocxFileUpload.PostedFile.FileName' est défini. sans ce code, ne peut pas vraiment aider – bnem

Répondre

1

Tout d'abord, vous devez savoir que les applications web, il y a deux machines au travail - le client (où le navigateur s'exécute) et le serveur (où vit votre application) .Chacun a son propre système de fichiers.Le serveur ne peut pas accéder au système de fichiers du client et vice versa- c'est pour des raisons évidentes de sécurité Maintenant, peut-être que cela fonctionne sur un développement machine car vous exécutez le site localement, mais cela ne fonctionnerait jamais dans un environnement de production. Par conséquent, Microsoft Word ne peut pas ouvrir un fichier qui se trouve sur l'ordinateur client. Cause Période. Le client peut télécharger un fichier, et le contrôle FileUpload vous permettra d'accéder au bytestream-- mais il ne sauvegarde pas automatiquement le fichier localement. Vous ne pouvez pas non plus accéder au chemin car le chemin est sur le système de fichiers du client et les noms de ses dossiers sont des informations privées.

Pour que ce système fonctionne, vous devez d'abord enregistrer le fichier téléchargé localement en utilisant FileUpload.SaveAs. Ensuite, vous devriez utiliser ce fichier enregistré pour l'ouvrir dans Word. Quelque chose comme ceci:

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

Vous devrez alors fournir des moyens d'obtenir le fichier converti au navigateur, by writing it to the HTTP response. Exemple:

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

Ne pas oublier de nettoyer vos fichiers après, ou vous serez à court d'espace disque que de plus en plus d'utilisateurs utilisent votre application:

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

je mets les commandes de suppression un bloc finally afin qu'ils courent même si quelque chose ne va pas, par exemple la requête expire. Vous avez besoin de ces fichiers pour être nettoyé, peu importe quoi. Vous pouvez également planifier une tâche système pour nettoyer le dossier tous les soirs, juste au cas où l'un des fichiers est verrouillé en raison de Word étant accroché, ce genre de chose.En outre, assurez-vous que l'application AppPool peut read and write to the temp folder.

Si vous souhaitez utiliser un gestionnaire distinct pour le téléchargement

Si vous souhaitez afficher un autre contenu à côté du PDF, vous devriez utiliser un gestionnaire distinct pour le téléchargement. Voici une esquisse:

Il y a trois URL utilisées dans cette solution:

  • Upload.aspx La page qui permet à l'utilisateur de spécifier un fichier pour le téléchargement
  • Confirm.asp La page affichée en réponse, qui comprend un grand iFrame
  • File.ashx le gestionnaire qui renvoie PDF qui est affiché dans l'iFrame

Vous avez un déjà codé Upload.aspx.

Confirm.aspx code requis pour accepter le téléchargement, enregistrer localement, ouvrir Word et convertir le fichier. Le chemin du fichier converti doit être converti en un jeton quelconque. La page doit ensuite renvoyer une page contenant un iFrame pointé au File.ashx?docID=token.

File.ashx doit définir les en-têtes de réponse, utiliser le jeton pour recréer le chemin du fichier PDF et renvoyer le fichier via HttpResponse. À un certain point, vous aurez besoin de comprendre comment nettoyer le dossier temporaire, peut-être avec un travail qui s'exécute régulièrement et supprime tout fichier .doc ou .pdf de plus de 10 minutes, ce genre de chose.

+0

Une ligne de code que vous avez fournie me laisse perplexe: 'var wordDoc = appWord.Documents.Open (docxFile);'. La valeur entre parenthèses ne devrait-elle pas être "filePath"? Cette variable contient le chemin d'accès complet et le nom de fichier du fichier enregistré. "DocxFile" est simplement le nom du fichier. Comment la méthode Open() trouverait-elle le fichier? –

+0

Vous avez raison. J'ai édité mon post. –

+0

Est-il nécessaire de créer un gestionnaire HTTP, comme cela est fait dans le lien que vous avez fourni? Ou le code ci-dessus peut-il être placé directement dans ma page ASP actuelle? Mes prochaines étapes sont d'afficher le fichier pdf sur l'écran, avec un bouton «enregistrer». En cliquant sur cela va l'enregistrer dans une base de données. Une fois que le fichier est dans l'objet Response, restera-t-il ou sera-t-il écrasé? –