Я пытаюсь преобразовать файл docx в pdf. Я использую код из stackoverflow, но изменен, чтобы разрешить динамический выбор файла для открытия (а не жестко заданное значение). Когда я запускаю его, я получаю исключение в методе Open () – не могу найти файл. Я выбираю файл с помощью элемента управления загрузкой файлов, чтобы знать, что файл там. Что происходит?
Вот мой код:
using System; using System.IO; using Microsoft.Office.Interop.Word; using OpenXmlPowerTools; пространство имен DocxToPdf {общедоступный частичный класс WebForm1: System.Web.UI.Page {общедоступный Microsoft.Office.Interop.Word.Document wordDoc; protected void Page_Load (отправитель объекта, EventArgs e) {} protected void UploadButton_Click (отправитель объекта, EventArgs e) {if (DocxFileUpload.HasFile) {string docxFile = DocxFileUpload.PostedFile.FileName; FileInfo fiFile = новый FileInfo (docxFile); если (Util.IsWordprocessingML (fiFile.Extension)) {Guid pdfFileGuid = Guid.NewGuid (); строка pdfFileLoc = string.Format (@ "c: windows temp {0} .pdf", pdfFileGuid.ToString ()); Microsoft.Office.Interop.Word.Application appWord = новый Microsoft.Office.Interop.Word.Application (); wordDoc = appWord.Documents.Open (docxFile); wordDoc.ExportAsFixedFormat (pdfFileLoc, WdExportFormat.wdExportFormatPDF); MsgLabel.Text = "Файл преобразован в PDF"; } else {MsgLabel.Text = "Не документ WordProcessingML."; }} else {MsgLabel.Text = "Вы не указали файл."; }}}}
Ошибка возникает в “wordDoc = appWord.Documents.Open (docxFile);” строка.
Свойство FileName элемента управления загрузкой файлов содержит только имя файла, а не полный путь. Я понимаю, почему я получаю сообщение об ошибке «файл не найден» – это потому, что в нем нет полного пути к файлу. Мой вопрос к группе: как мне получить полный путь и имя файла, чтобы я мог его открыть? Я запустил сеанс отладки и изучил все свойства элемента управления загрузкой файла и элемента управления FileInfo, но у них его нет. Свойство FullPath элемента управления FileInfo имеет значение «c: Program Files (x86) IIS Express myfile.docx», но файл находится не там.
Вот некоторые из них. дополнительная информация об ошибке: Exception System.Runtime.InteropServices.COMException в DocxToPdf.dll (К сожалению, нам не удалось найти ваш файл. Возможно, он был перемещен, переименован или удален? C: Windows … myfile. docx …
Я искал это в Google, но пока безуспешно. Пожалуйста, помогите! Спасибо.
Во-первых, вы Следует помнить, что с веб-приложениями работают две машины – клиент (на котором работает браузер) и сервер (на котором находится ваше приложение). У каждого из них своя файловая система. Сервер не может получить доступ к файловой системе клиента и наоборот. наоборот – это из очевидных соображений безопасности. Теперь, возможно, он работает на машине разработки, потому что вы запускаете сайт локально, но никогда не будет работать в производственной среде.
Таким образом, 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 convertFilePath = Path.GetTempFileName (); wordDoc.ExportAsFixedFormat (convertFilePath, WdExportFormat.wdExportFormatPDF);
После этого вам потребуется предоставить некоторые средства для возврата преобразованного файла в браузер, записав его в ответ HTTP. Пример:
Response.Clear (); Response.AddHeader ("content-disposition", "attachment; filename = Converted.Pdf"); Response.AddHeader ("content- тип "," приложение/pdf "); Response.TransmitFile (convertFilePath);
Не забудьте после этого очистить свои файлы, иначе у вас закончится место на диске, поскольку ваше приложение будет использовать все больше и больше пользователей:
} наконец {File.Delete (filePath); File.Delete (convertFilePath);}
Я помещаю команды удаления в блок finally
, чтобы они выполнялись, даже если что-то пойдет не так, например время запроса истекло. Вам нужны эти файлы, чтобы их очистить, несмотря ни на что. Вы также можете запланировать системную задачу по очистке папки каждую ночь, на случай, если один из файлов заблокирован из-за зависания Word и тому подобного.
Кроме того, убедитесь, что AppPool вашего приложения может читать и записывать во временную папку.
Если вы хотите использовать отдельный обработчик для загрузки
Если вы хотите отображать другое содержимое вместе с PDF, вам придется использовать отдельный обработчик для загрузки. Вот приблизительный план:
В этом решении используются три URL-адреса:
-
Upload.aspx
страница, которая позволяет пользователю указать файл для загрузки. -
Confirm.asp
Страница, отображаемая в ответе, которая включает большой iFrame -
File.ashx
Обработчик, который возвращает PDF-файл, отображаемый в iFrame
Вы уже кодировали Upload.aspx
.
Confirm.aspx
требуется код для принятия загрузки, сохранения локально, открытия Word и преобразования файла.. Путь к преобразованному файлу необходимо преобразовать в какой-то токен. Затем страница должна вернуть страницу, содержащую iFrame с указанием на File.ashx? DocID = token
.
File.ashx
необходимо установить заголовки ответа, использовать токен для воссоздания пути к файлу PDF и вернуть файл через HttpResponse.
В какой-то момент вам нужно будет выяснить, как очистить вверх по временной папке, возможно, с помощью задания, которое выполняется регулярно и удаляет все файлы .doc или .pdf старше 10 минут и тому подобное.