首页 > 解决方案 > 在 MVC 中找不到文件

问题描述

制作将数据导出为 word 的 MVC (.Net5.0)。使用运行良好的 web 表单进行了同样的操作,但是在 MVC 中执行此操作时,会出现“System.IO.FileNotFoundException”。弹出系统找不到指定文件的错误。我找不到什么问题,因为我在控制台应用程序和 Web 表单中以相同的方式定位我的文件,或者是否有其他方法可以在 MVC 中定位本地文件?无论我使用什么库,代码在 webforms/console 应用程序上都可以正常工作,但在 MVC 上也有同样的问题。谁能告诉我如何在 MVC 中找到本地文件/目录。感谢您的时间。

FileName= "office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"  string

StackTrace="
at findandreplacemvc.Controllers.DocxController.CreateWordDocument(Object filename, Object SaveAs) 
in D:\\Files\\C#\\findandreplacemvc\\findandreplacemvc\\Controllers\\DocxController.cs:line 113\r\n   
at findandreplacemvc.Controllers.DocxController.generateDocx() in D:\\Files\\C#\\findandreplacemvc\\findandreplacemvc\\Controllers\\DocxController.cs:line 24\r\n   
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)\r\n   
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()\r\n   
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()" string

代码:

public class DocxController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult generateDocx()
        {
            var f1 = @"D:\docs\templateFile.docx";
            var f2 = @"D:\docs\replacedFile.docx";
            CreateWordDocument(f1 , f2);
            return Ok("done");
        }

        private void FindAndReplace(Microsoft.Office.Interop.Word.Application wordApp, object findText, object replaceWithText)
        {
            //options
            object matchCase = true;

            object matchwholeWord = true;

            object matchwildCards = false;

            object matchSoundLike = false;

            object nmatchAllforms = false;

            object forward = true;

            object format = false;

            object matchKashida = false;

            object matchDiactitics = false;

            object matchAlefHamza = false;

            object matchControl = false;

            object read_only = false;

            object visible = true;

            object replace = 2;

            object wrap = 1;

            wordApp.Selection.Find.Execute(ref findText, ref matchCase,
                                            ref matchwholeWord, ref matchwildCards, ref matchSoundLike,

                                            ref nmatchAllforms, ref forward,

                                            ref wrap, ref format, ref replaceWithText,

                                                ref replace, ref matchKashida,

                                            ref matchDiactitics, ref matchAlefHamza,

                                             ref matchControl);
        }

        private void CreateWordDocument(object filename, object SaveAs)
        {
            Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application();
            object missing = Missing.Value;

            Microsoft.Office.Interop.Word.Document myWordDoc = null;

            if (System.IO.File.Exists((string)filename))
            {
                object readOnly = false;

                object isvisible = false;

                wordApp.Visible = false;
                myWordDoc = wordApp.Documents.Open(ref filename, ref missing, ref readOnly,
                                                    ref missing, ref missing, ref missing,
                                                    ref missing, ref missing, ref missing,
                                                    ref missing, ref missing, ref missing,
                                                     ref missing, ref missing, ref missing, ref missing);
                myWordDoc.Activate();

                //Find and Replace
                this.FindAndReplace(wordApp, "varName", "Anything");
                this.FindAndReplace(wordApp, "varAddress", "Anything");

                myWordDoc.SaveAs2(ref SaveAs, ref missing, ref missing, ref missing,
                                                                ref missing, ref missing, ref missing,
                                                                ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
                                                                ref missing, ref missing, ref missing);

                myWordDoc.Close();
                wordApp.Quit();
            }
        }
    }
}

标签: .netasp.net-mvcoffice-interop

解决方案


FileNotFoundException。

这与 MVC 无关。MVC 的年龄足以上高中(2009 年发布),所以如果有这样的问题,每个 .NET 开发人员都会在几年前遇到它。

某些路径错误或 Web 应用程序无权从该路径读取。在不知道哪条线抛出的情况下,很难说可能是什么问题。

  • 应用程序池帐户仅有权读取 Web 应用程序文件夹中的文件。这不是 MVC 问题,IIS 本身强制执行该限制。但是,在使用 IIS Express 进行调试时,这可能并不明显。
  • 该文件夹可能不存在。
  • 模板文件可能不存在

生成 Word 文档

这也不适用于 WebForms,原因如下:

  • 您需要为网站的每个用户提供 Word 许可证,即使他们是匿名的。
  • 将孤立的 Word 版本留在内存中太容易了,这会占用服务器的内存,直到它爬到停止为止
  • 该代码不会在出现错误时关闭 Word,也不会处理 COM 对象,从而导致孤立的 Word 实例。

您不需要 Word 来创建 Word 文档。自 2007 年以来,该docx格式允许应用程序直接创建适当的文档。docx是一个定义明确的格式的包含 ZIP 的 XML 文件。您可以直接创建这些文件,使用 Microsoft 的Open Offixe XML SDKNPOI之类的库,只需几行即可生成 Word 文件。如果你在NuGet 中搜索 docx,你会发现 200 多个结果。NPOI 可能是最受欢迎的,下载量为 1300 万。

文本替换示例在不到 10 行的时间内与您的程序执行相同的操作:

        var template = @"Template1.docx";
        using (var rs = File.OpenRead(template))
        {

            var generateFile = @"output1.docx";
            using (var ws = File.Create(generateFile))
            {
                var doc = new XWPFDocument(rs);

                foreach (var para in doc.Paragraphs)
                {
                    foreach (var placeholder in placeHolderDictionary)
                    {
                        if (para.ParagraphText.Contains(placeholder))
                        {
                            para.ReplaceText(placeholder, "Nissl");
                        }
                    }
                }
                doc.Write(ws);
            }
        }

该文件保存到带有doc.Write(ws). 该流很容易成为WebForms 或 MVC 中的响应流,允许您将文件直接发送到浏览器。


推荐阅读