使用IRONWORD

ASP .NET Core 匯入與匯出 Word 文件

發佈 2024年12月16日
分享:

介紹

本指南探討如何導入現有的Word文件、顯示其內容,並使用IronWord從頭開始創建文件。IronWord 函式庫. 在本教程結束時,您將創建一個ASP.NET Core可以實現以下功能的網路應用程式:

  1. 上傳並閱讀 Word 文件

  2. 在文本框中顯示這些文件的內容

  3. 匯出 Docx 文件

    此專案非常適合需要將 Word 文件處理整合到其網頁應用程式中的開發人員,無論是用於文件管理系統、報告生成器,或是任何其他涉及 Microsoft Word 文件的場景。

先決條件

要跟隨本教程,您應該具備:

  • C#和ASP.NET Core的基本知識
  • 安裝 Visual Studio 2019 或更高版本(或者,您可以使用帶有C#擴展的Visual Studio Code)
  • .NET Core SDK 3.1 或更高版本

    如果您不是這些技術的專家,也不用擔心——我們會指導您完成每個步驟。!

什麼是IronWord?

IronWord是一個 .NET 資料庫,允許開發人員以程式化方式讀取、操作和建立 Microsoft Word 文件。 它提供了高級 API,簡化了處理 Word 文件的過程,使其成為我們項目的極佳選擇。

IronWord 的一些主要功能包括:

  • 閱讀和编写各种 Word 格式 (DOCX、DOC 等。)
  • 操作文件內容及結構
  • 格式化文字和段落
  • 處理表格、圖像和其他文檔元素
  • 文件的郵件合併過程
  • 輕鬆地將 Word 文件轉換為 PDF 文件,這樣您就可以將最終的 Word 文件製作成易於共享的 PDF 文件。

    現在我們對我們要構建的內容和將使用的工具有了一個概覽,讓我們開始著手設置我們的專案。!

2. 設置專案

在本節中,我們將創建一個新的 ASP.NET Core 專案並安裝必要的套件以使用 IronWord。

2.1 建立新的 ASP.NET Core 專案

  1. 打開 Visual Studio 2019 或更高版本。

  2. 點擊「創建新專案」。

    1. 搜索「ASP.NET Core Web Application」並選擇它。

    損壞的圖像 從Pixabay添加,從檔案中選擇或拖放圖像至此處。

  3. 點擊「下一步」。

  4. 將您的專案命名為 "WordDocumentProcessor"(或任何您喜歡的名稱).

  5. 選擇 .NET Framework 和項目位置,然後點擊「建立」。

2.2 安裝 IronWord NuGet 套件

現在我們已經設置好項目,讓我們添加IronWord庫:

  1. 在方案總管中右鍵點擊你的專案。

  2. 選擇「管理 NuGet 套件」。

    1. 在「瀏覽」標籤中,搜索「IronWord」。

    損壞的圖像 從Pixabay添加,從檔案中選擇或拖放圖像至此處。

  3. 查找官方的IronWord套件。

  4. 點擊「安裝」將其添加到您的專案中。

2.3 更新現有的控制器和視圖

讓我們更新現有的結構以整合文件處理功能:

  1. 我們將使用控制器資料夾中的現有 HomeController.cs 來處理我們的文件處理邏輯。

  2. 我們將更新 Views/Home 資料夾中的現有 Index.cshtml 視圖,以納入文件上傳和顯示功能。

    現在我們已經設置好項目並安裝了IronWord套件,準備開始實施文件匯入和導出功能。 我們將在 HomeController 中新增方法並修改 Index 視圖來處理這些功能。 在下一節中,我們將專注於匯入 Word 文件並顯示其內容,利用我們現有的控制器和視圖結構。 我們也可以添加郵件合併功能,但本文將重點放在匯入和匯出文件上。

3. 匯入 Word 文件

在本節中,我們將探討如何在 ASP.NET MVC 應用程式中實現導入和處理 Word 文件的功能。 我們將涵蓋使用者介面設計和後端控制器邏輯。

3.1 使用者介面設計

匯入 Word 文件的使用者介面設計得直觀且視覺上具有吸引力。 讓我們分解 UI 的關鍵組成部分:

3.1.1 上傳區域

上傳區域是介面的焦點,邀請用戶選擇並上傳他們的 Word 文件。 以下是結構說明:

<div class="upload-area">
    <svg class="file-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
    <polyline points="14 2 14 8 20 8"></polyline>
    <line x1="16" y1="13" x2="8" y2="13"></line>
    <line x1="16" y1="17" x2="8" y2="17"></line>
    <polyline points="10 9 9 9 8 9"></polyline>
</svg>
    <p>Choose a Word document</p>
    <label for="fileInput" class="choose-file">Choose File</label>
    <p class="file-info">.DOC or .DOCX (MAX. 10MB)</p>
    <button id="uploadBtn" class="upload-button">Upload and Process</button>
</div>
<div class="upload-area">
    <svg class="file-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
    <polyline points="14 2 14 8 20 8"></polyline>
    <line x1="16" y1="13" x2="8" y2="13"></line>
    <line x1="16" y1="17" x2="8" y2="17"></line>
    <polyline points="10 9 9 9 8 9"></polyline>
</svg>
    <p>Choose a Word document</p>
    <label for="fileInput" class="choose-file">Choose File</label>
    <p class="file-info">.DOC or .DOCX (MAX. 10MB)</p>
    <button id="uploadBtn" class="upload-button">Upload and Process</button>
</div>
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'<div class="upload-area"> <svg class="file-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> <p> Choose a Word document</p> <label for="fileInput" class="choose-file"> Choose File</label> <p class="file-info">.DOC @or.DOCX(MAX. 10MB)</p> <button id="uploadBtn" class="upload-button"> Upload @and Process</button> </div>
VB   C#

此代碼創建了一個視覺上吸引人的上傳區域,具有文件圖標、隱藏的文件輸入,以及充當文件選擇按鈕的樣式標籤。 它還包括有關可接受文件類型的信息以及一個用於啟動上傳和處理的按鈕。

3.1.2 內容顯示區域

處理完文件後,其內容將顯示在專用區域中:

<div class="content-wrapper">
    <h2>Document Content:</h2>
    <div id="documentContent" class="content-area">
        No content to display.
    </div>
</div>
<div class="content-wrapper">
    <h2>Document Content:</h2>
    <div id="documentContent" class="content-area">
        No content to display.
    </div>
</div>
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'<div class="content-wrapper"> <h2> Document Content:</h2> <div id="documentContent" class="content-area"> No content @to display. </div> </div>
VB   C#

此區域提供了一個可滾動的區域來顯示處理過的文件內容。

3.2 控制器實現

HomeController 負責處理匯入和處理 Word 文件的伺服器端邏輯。 我們來檢視主要的方法:

3.2.1 UploadAndProcess 方法

此方法負責處理文件上傳和處理:

[HttpPost]
public IActionResult UploadAndProcess(IFormFile file)
{
    if (file == null 
 file.Length == 0)
    {
        return Json(new { success = false, message = "No file uploaded." });
    }
    var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant();
    if (fileExtension != ".doc" && fileExtension != ".docx")
    {
        return Json(new { success = false, message = "Invalid file type. Please upload a .doc or .docx file." });
    }
    try
    {
        var tempFilePath = Path.GetTempFileName();
        using (var stream = new FileStream(tempFilePath, FileMode.Create))
        {
            file.CopyTo(stream);
        }
        StringBuilder contentBuilder = new StringBuilder();
        WordDocument doc = new WordDocument(tempFilePath);
        foreach (Paragraph paragraph in doc.Paragraphs)
        {
            foreach (Text textRun in paragraph.Texts)
            {
                contentBuilder.AppendLine(textRun.Text);
            }
            contentBuilder.AppendLine(); // Add an extra line between paragraphs
        }
        System.IO.File.Delete(tempFilePath); // Clean up the temporary file
        return Json(new { success = true, content = FormatContentAsHtml(contentBuilder.ToString()) });
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error processing document");
        return Json(new { success = false, message = "An error occurred while processing the document." });
    }
}
[HttpPost]
public IActionResult UploadAndProcess(IFormFile file)
{
    if (file == null 
 file.Length == 0)
    {
        return Json(new { success = false, message = "No file uploaded." });
    }
    var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant();
    if (fileExtension != ".doc" && fileExtension != ".docx")
    {
        return Json(new { success = false, message = "Invalid file type. Please upload a .doc or .docx file." });
    }
    try
    {
        var tempFilePath = Path.GetTempFileName();
        using (var stream = new FileStream(tempFilePath, FileMode.Create))
        {
            file.CopyTo(stream);
        }
        StringBuilder contentBuilder = new StringBuilder();
        WordDocument doc = new WordDocument(tempFilePath);
        foreach (Paragraph paragraph in doc.Paragraphs)
        {
            foreach (Text textRun in paragraph.Texts)
            {
                contentBuilder.AppendLine(textRun.Text);
            }
            contentBuilder.AppendLine(); // Add an extra line between paragraphs
        }
        System.IO.File.Delete(tempFilePath); // Clean up the temporary file
        return Json(new { success = true, content = FormatContentAsHtml(contentBuilder.ToString()) });
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error processing document");
        return Json(new { success = false, message = "An error occurred while processing the document." });
    }
}
<HttpPost>
Public Function UploadAndProcess(ByVal file As IFormFile) As IActionResult
	If file Is Nothing file.Length = 0 Then
		Return Json(New With {
			Key .success = False,
			Key .message = "No file uploaded."
		})
	End If
	Dim fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant()
	If fileExtension <> ".doc" AndAlso fileExtension <> ".docx" Then
		Return Json(New With {
			Key .success = False,
			Key .message = "Invalid file type. Please upload a .doc or .docx file."
		})
	End If
	Try
		Dim tempFilePath = Path.GetTempFileName()
		Using stream = New FileStream(tempFilePath, FileMode.Create)
			file.CopyTo(stream)
		End Using
		Dim contentBuilder As New StringBuilder()
		Dim doc As New WordDocument(tempFilePath)
		For Each paragraph As Paragraph In doc.Paragraphs
			For Each textRun As Text In paragraph.Texts
				contentBuilder.AppendLine(textRun.Text)
			Next textRun
			contentBuilder.AppendLine() ' Add an extra line between paragraphs
		Next paragraph
		System.IO.File.Delete(tempFilePath) ' Clean up the temporary file
		Return Json(New With {
			Key .success = True,
			Key .content = FormatContentAsHtml(contentBuilder.ToString())
		})
	Catch ex As Exception
		_logger.LogError(ex, "Error processing document")
		Return Json(New With {
			Key .success = False,
			Key .message = "An error occurred while processing the document."
		})
	End Try
End Function
VB   C#

此方法執行以下任務:

  1. 驗證上傳的檔案,確保其為正確的檔案格式。(DOC 或 DOCX)

  2. 檢查正確的檔案擴展名

  3. 使用IronWord庫處理文件

  4. 將格式化內容作為 JSON 返回

3.2.2 FormatContentAsHtml 方法

此私有方法將提取的內容格式化為HTML:

private string FormatContentAsHtml(string content)
{
    var lines = content.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
    var htmlBuilder = new StringBuilder();
    htmlBuilder.Append("<div class='document-content'>");
    foreach (var line in lines)
    {
        if (string.IsNullOrWhiteSpace(line))
        {
            htmlBuilder.Append("<p> </p>");
        }
        else
        {
            htmlBuilder.Append($"<p>{HttpUtility.HtmlEncode(line)}</p>");
        }
    }
    htmlBuilder.Append("</div>");
    return htmlBuilder.ToString();
}
private string FormatContentAsHtml(string content)
{
    var lines = content.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
    var htmlBuilder = new StringBuilder();
    htmlBuilder.Append("<div class='document-content'>");
    foreach (var line in lines)
    {
        if (string.IsNullOrWhiteSpace(line))
        {
            htmlBuilder.Append("<p> </p>");
        }
        else
        {
            htmlBuilder.Append($"<p>{HttpUtility.HtmlEncode(line)}</p>");
        }
    }
    htmlBuilder.Append("</div>");
    return htmlBuilder.ToString();
}
Private Function FormatContentAsHtml(ByVal content As String) As String
	Dim lines = content.Split( { Environment.NewLine }, StringSplitOptions.None)
	Dim htmlBuilder = New StringBuilder()
	htmlBuilder.Append("<div class='document-content'>")
	For Each line In lines
		If String.IsNullOrWhiteSpace(line) Then
			htmlBuilder.Append("<p> </p>")
		Else
			htmlBuilder.Append($"<p>{HttpUtility.HtmlEncode(line)}</p>")
		End If
	Next line
	htmlBuilder.Append("</div>")
	Return htmlBuilder.ToString()
End Function
VB   C#

此方法確保文件內容正確格式化為HTML,每行都用段落標籤包裹,並保留空行。

3.3 客戶端 JavaScript

為了處理文件上傳並顯示處理後的內容,我們使用 JavaScript:

uploadBtn.addEventListener('click', () => {
    const file = fileInput.files[0];
    if (!file) {
        alert('Please select a file first.');
        return;
    }
    const formData = new FormData();
    formData.append('file', file);
    uploadBtn.disabled = true;
    uploadBtn.textContent = 'Processing...';
    documentContent.innerHTML = 'Processing document...';
    fetch('/Home/UploadAndProcess', {
        method: 'POST',
        body: formData
    })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                documentContent.innerHTML = data.content;
            } else {
                documentContent.innerHTML = `<p>Error: ${data.message}</p>`;
            }
        })
        .catch(error => {
            console.error('Error:', error);
            documentContent.innerHTML = '<p>An error occurred while processing the document.</p>';
        })
        .finally(() => {
            uploadBtn.disabled = false;
            uploadBtn.textContent = 'Upload and Process';
        });
});
uploadBtn.addEventListener('click', () => {
    const file = fileInput.files[0];
    if (!file) {
        alert('Please select a file first.');
        return;
    }
    const formData = new FormData();
    formData.append('file', file);
    uploadBtn.disabled = true;
    uploadBtn.textContent = 'Processing...';
    documentContent.innerHTML = 'Processing document...';
    fetch('/Home/UploadAndProcess', {
        method: 'POST',
        body: formData
    })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                documentContent.innerHTML = data.content;
            } else {
                documentContent.innerHTML = `<p>Error: ${data.message}</p>`;
            }
        })
        .catch(error => {
            console.error('Error:', error);
            documentContent.innerHTML = '<p>An error occurred while processing the document.</p>';
        })
        .finally(() => {
            uploadBtn.disabled = false;
            uploadBtn.textContent = 'Upload and Process';
        });
});
uploadBtn.addEventListener( 'click', () =>
If True Then
	const file = fileInput.files(0)
	If Not file Then
		alert( 'Please select a file first.');
		Return
	End If
	const formData = New FormData()
	formData.append( 'file', file);
	uploadBtn.disabled = True
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'	uploadBtn.textContent = 'Processing...'; documentContent.innerHTML = 'Processing document...'; fetch('/Home/UploadAndProcess', { method: 'POST', body: formData }).@then(response => response.json()).@then(data => { if(data.success) { documentContent.innerHTML = data.content; } else { documentContent.innerHTML = `<p> @Error: ${data.message}</p>`; } }).catch(@error => { console.@error('@Error:', @error); documentContent.innerHTML = '<p> An @error occurred while processing the document.</p>'; }).finally(() => { uploadBtn.disabled = False; uploadBtn.textContent = 'Upload @and Process'; }); });
VB   C#

此 JavaScript 程式碼處理檔案上傳過程,將檔案傳送到伺服器進行處理,並使用處理過的內容或錯誤訊息更新使用者介面。

3.4 樣式化使用者介面

該應用程式使用自訂 CSS 來創建一個吸引人且使用者友好的介面。

<style>
    body {
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        background-color: #f7f7f7;
        color: #333;
    }
    .container {
        max-width: 800px;
        margin: 0 auto;
        padding: 2rem;
        padding-top: 0.5rem;
    }
    h1 {
        font-weight: 300;
        color: #2c3e50;
        text-align: center;
        margin-bottom: 1rem;
    }
    .lead {
        text-align: center;
        color: #7f8c8d;
        margin-bottom: 2rem;
    }
    .upload-area {
        background-color: #ffffff;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        padding: 2rem;
        text-align: center;
        margin-bottom: 2rem;
        transition: all 0.3s ease;
    }
        .upload-area:hover {
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
        }
    .file-icon {
        width: 64px;
        height: 64px;
        margin-bottom: 1rem;
        color: #3498db;
    }
    .choose-file {
        background-color: #ecf0f1;
        color: #2c3e50;
        border: none;
        padding: 0.5rem 1rem;
        border-radius: 4px;
        cursor: pointer;
        transition: background-color 0.3s ease;
    }
        .choose-file:hover {
            background-color: #d5dbdb;
        }
    .file-info {
        font-size: 0.9em;
        color: #95a5a6;
        margin-top: 0.5rem;
    }
    .upload-button {
        background-color: #3498db;
        color: white;
        border: none;
        padding: 0.75rem 1.5rem;
        border-radius: 4px;
        cursor: pointer;
        transition: background-color 0.3s ease;
        margin-top: 1rem;
    }
        .upload-button:hover {
            background-color: #2980b9;
        }
    .content-wrapper {
        background-color: #ffffff;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        padding: 1rem;
        margin-top: 2rem;
    }
    .content-area {
        max-height: 300px;
        overflow-y: auto;
        padding: 1rem;
        background-color: #f9f9f9;
        border-radius: 4px;
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        font-size: 14px;
        line-height: 1.6;
    }
        .content-area::-webkit-scrollbar {
            width: 8px;
        }
        .content-area::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 4px;
        }
        .content-area::-webkit-scrollbar-thumb {
            background: #bdc3c7;
            border-radius: 4px;
        }
            .content-area::-webkit-scrollbar-thumb:hover {
                background: #95a5a6;
            }
    .document-content p {
        margin: 0 0 10px 0;
    }
</style>
<style>
    body {
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        background-color: #f7f7f7;
        color: #333;
    }
    .container {
        max-width: 800px;
        margin: 0 auto;
        padding: 2rem;
        padding-top: 0.5rem;
    }
    h1 {
        font-weight: 300;
        color: #2c3e50;
        text-align: center;
        margin-bottom: 1rem;
    }
    .lead {
        text-align: center;
        color: #7f8c8d;
        margin-bottom: 2rem;
    }
    .upload-area {
        background-color: #ffffff;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        padding: 2rem;
        text-align: center;
        margin-bottom: 2rem;
        transition: all 0.3s ease;
    }
        .upload-area:hover {
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
        }
    .file-icon {
        width: 64px;
        height: 64px;
        margin-bottom: 1rem;
        color: #3498db;
    }
    .choose-file {
        background-color: #ecf0f1;
        color: #2c3e50;
        border: none;
        padding: 0.5rem 1rem;
        border-radius: 4px;
        cursor: pointer;
        transition: background-color 0.3s ease;
    }
        .choose-file:hover {
            background-color: #d5dbdb;
        }
    .file-info {
        font-size: 0.9em;
        color: #95a5a6;
        margin-top: 0.5rem;
    }
    .upload-button {
        background-color: #3498db;
        color: white;
        border: none;
        padding: 0.75rem 1.5rem;
        border-radius: 4px;
        cursor: pointer;
        transition: background-color 0.3s ease;
        margin-top: 1rem;
    }
        .upload-button:hover {
            background-color: #2980b9;
        }
    .content-wrapper {
        background-color: #ffffff;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        padding: 1rem;
        margin-top: 2rem;
    }
    .content-area {
        max-height: 300px;
        overflow-y: auto;
        padding: 1rem;
        background-color: #f9f9f9;
        border-radius: 4px;
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        font-size: 14px;
        line-height: 1.6;
    }
        .content-area::-webkit-scrollbar {
            width: 8px;
        }
        .content-area::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 4px;
        }
        .content-area::-webkit-scrollbar-thumb {
            background: #bdc3c7;
            border-radius: 4px;
        }
            .content-area::-webkit-scrollbar-thumb:hover {
                background: #95a5a6;
            }
    .document-content p {
        margin: 0 0 10px 0;
    }
</style>
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'(Of style) body
'{
''INSTANT VB TODO TASK: The following line uses invalid syntax:
''		font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f7f7f7; color: #333; } .container { max-width: 800px; margin: 0 auto; padding: 2rem; padding-top: 0.5rem; } h1 { font-weight: 300; color: #2c3e50; text-align: center; margin-bottom: 1rem; } .lead { text-align: center; color: #7f8c8d; margin-bottom: 2rem; } .upload-area { background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); padding: 2rem; text-align: center; margin-bottom: 2rem; transition: all 0.3s ease; } .upload-area:hover { box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); } .file-icon { width: 64px; height: 64px; margin-bottom: 1rem; color: #3498db; } .choose-file { background-color: #ecf0f1; color: #2c3e50; border: none; padding: 0.5rem 1rem; border-radius: 4px; cursor: pointer; transition: background-color 0.3s ease; } .choose-file:hover { background-color: #d5dbdb; } .file-info { font-size: 0.9em; color: #95a5a6; margin-top: 0.5rem; } .upload-button { background-color: #3498db; color: white; border: none; padding: 0.75rem 1.5rem; border-radius: 4px; cursor: pointer; transition: background-color 0.3s ease; margin-top: 1rem; } .upload-button:hover { background-color: #2980b9; } .content-wrapper { background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); padding: 1rem; margin-top: 2rem; } .content-area { max-height: 300px; overflow-y: auto; padding: 1rem; background-color: #f9f9f9; border-radius: 4px; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-size: 14px; line-height: 1.6; } .content-area::-webkit-scrollbar { width: 8px; } .content-area::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 4px; } .content-area::-webkit-scrollbar-thumb { background: #bdc3c7; border-radius: 4px; } .content-area::-webkit-scrollbar-thumb:hover { background: #95a5a6; } .document-content p { margin: 0 0 10px 0; } </style>
VB   C#

這個 CSS 創建了一個乾淨、現代的外觀,具有輕盈的色彩方案。 上傳區域具有白色背景和微妙的陰影效果,而內容區域則設計為可捲動、淺灰色背景。 使用 border-radius 和 box-shadow 屬性可以為介面元素添加深度和視覺趣味。

4. 匯出 Word 文件

隨著我們不斷改進我們的文字文件處理器,讓我們新增文件匯出的功能。 此功能將允許用戶從我們的應用程式生成新的 Word 文件。

4.1 更新使用者介面

首先,我們將在導航欄中添加一個「匯出」選項。 在 Views/Shared 資料夾中打開 _Layout.cshtml 文件,然後找到

元素。 讓我們為匯出功能新增一個清單項目:

<li class="nav-item">
    <a class="nav-link" id="exportLink" href="#" onclick="exportDocument(); return false;"><i class="fas fa-file-export"></i> Export</a>
</li>
<li class="nav-item">
    <a class="nav-link" id="exportLink" href="#" onclick="exportDocument(); return false;"><i class="fas fa-file-export"></i> Export</a>
</li>
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'<li class="nav-item"> <a class="nav-link" id="exportLink" href="#" onclick="exportDocument(); return false;"><i class="fas fa-file-export"></i> Export</a> </li>
VB   C#

我們正在使用 Font Awesome 作為圖示,因此確保我們在我們的 CSS 連結中包含它。

部分。 此程式碼在導航欄中新增一個「匯出」連結。 它使用 Font Awesome 作為圖示並呼叫 exportDocument() 在點擊時的功能。 href="#" 和 return false 防止了預設的連結行為。

4.2 實現客戶端匯出邏輯

現在,讓我們添加將處理匯出過程的 JavaScript 函數。 At the bottom of our _Layout.cshtml file, just before the closing

tag, we'll add the following script:

<script>
function exportDocument() {
    $.ajax({
        url: '/Home/ExportWordDocument',
        type: 'POST',
        success: function (response) {
            if (response.success) {
                var fileName = prompt("Enter a name for the document (without extension):", "ExportedDocument");
                if (fileName === null) {
                    return;
                }
                fileName = (fileName.trim() 
 "ExportedDocument").replace(/\.[^/.]+$/, "") + ".docx";
                var a = document.createElement('a');
                a.style.display = 'none';
                a.href = '/Home/DownloadFile?tempFilePath=' + encodeURIComponent(response.tempFilePath) + '&userFileName=' + encodeURIComponent(fileName);
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
            } else {
                alert('Failed to export document: ' + response.message);
            }
        },
        error: function () {
            alert('An error occurred while exporting the document.');
        }
    });
}
</script>
<script>
function exportDocument() {
    $.ajax({
        url: '/Home/ExportWordDocument',
        type: 'POST',
        success: function (response) {
            if (response.success) {
                var fileName = prompt("Enter a name for the document (without extension):", "ExportedDocument");
                if (fileName === null) {
                    return;
                }
                fileName = (fileName.trim() 
 "ExportedDocument").replace(/\.[^/.]+$/, "") + ".docx";
                var a = document.createElement('a');
                a.style.display = 'none';
                a.href = '/Home/DownloadFile?tempFilePath=' + encodeURIComponent(response.tempFilePath) + '&userFileName=' + encodeURIComponent(fileName);
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
            } else {
                alert('Failed to export document: ' + response.message);
            }
        },
        error: function () {
            alert('An error occurred while exporting the document.');
        }
    });
}
</script>
Private Function exportDocument() As [function](Of script)
	$.ajax({ url: '/Home/ExportWordDocument', type: 'POST', success: @function(response) { if(response.success) { var fileName = prompt("Enter a name for the document (without extension):", "ExportedDocument"); if(fileName === Nothing) { Return; } fileName = (fileName.trim() "ExportedDocument").replace(/\.[^/.]+$/, "") + ".docx"; var a = document.createElement("a"c); a.style.display = 'none'; a.href = '/Home/System.Nullable<DownloadFile>tempFilePath=' + encodeURIComponent(response.tempFilePath) + '&userFileName=' + encodeURIComponent(fileName); document.body.appendChild(a); a.click(); document.body.removeChild(a); } else { alert('Failed @to export document: ' + response.message); } }, @error: @function() { alert('An @error occurred while exporting the document.'); } });
 End Function
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'</script>
VB   C#

此 JavaScript 函數發送 AJAX POST 請求到伺服器以創建 Word 文件。 成功後,系統會提示使用者輸入文件名稱,然後創建一個臨時連結以下載該文件。連結會自動被點擊,隨後從 DOM 中移除。 如果在任何階段發生錯誤,會向用戶顯示一個警告。

4.3 添加伺服器端匯出功能

現在,讓我們實現伺服器端邏輯。 在 Controllers 資料夾中打開 HomeController.cs 文件。 我們將新增兩個方法來處理匯出流程。

首先,我們來添加建立 Word 文件的方法:

[HttpPost]
public IActionResult ExportWordDocument()
{
    try
    {
        WordDocument doc = new WordDocument();
        doc.AddText("Test Word");
        string tempFileName = $"TempDoc_{Guid.NewGuid()}.docx";
        string tempFilePath = Path.Combine(_environment.WebRootPath, "TempFiles", tempFileName);
        Directory.CreateDirectory(Path.GetDirectoryName(tempFilePath));
        doc.SaveAs(tempFilePath);
        return Json(new { success = true, tempFilePath = $"/TempFiles/{tempFileName}" });
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error exporting Word document");
        return Json(new { success = false, message = "An error occurred while exporting the document." });
    }
}
[HttpPost]
public IActionResult ExportWordDocument()
{
    try
    {
        WordDocument doc = new WordDocument();
        doc.AddText("Test Word");
        string tempFileName = $"TempDoc_{Guid.NewGuid()}.docx";
        string tempFilePath = Path.Combine(_environment.WebRootPath, "TempFiles", tempFileName);
        Directory.CreateDirectory(Path.GetDirectoryName(tempFilePath));
        doc.SaveAs(tempFilePath);
        return Json(new { success = true, tempFilePath = $"/TempFiles/{tempFileName}" });
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error exporting Word document");
        return Json(new { success = false, message = "An error occurred while exporting the document." });
    }
}
<HttpPost>
Public Function ExportWordDocument() As IActionResult
	Try
		Dim doc As New WordDocument()
		doc.AddText("Test Word")
		Dim tempFileName As String = $"TempDoc_{Guid.NewGuid()}.docx"
		Dim tempFilePath As String = Path.Combine(_environment.WebRootPath, "TempFiles", tempFileName)
		Directory.CreateDirectory(Path.GetDirectoryName(tempFilePath))
		doc.SaveAs(tempFilePath)
		Return Json(New With {
			Key .success = True,
			Key .tempFilePath = $"/TempFiles/{tempFileName}"
		})
	Catch ex As Exception
		_logger.LogError(ex, "Error exporting Word document")
		Return Json(New With {
			Key .success = False,
			Key .message = "An error occurred while exporting the document."
		})
	End Try
End Function
VB   C#

此方法使用IronWord庫創建一個新的Word文檔,添加一些測試文本,並將其保存到具有唯一名稱的臨時文件中。 它返回一個 JSON 對象,其中包含成功狀態和臨時文件的路徑。如果發生錯誤,則會記錄異常並返回失敗消息。

接下來,讓我們添加方法來處理文件下載:

[HttpGet]
public IActionResult DownloadFile(string tempFilePath, string userFileName)
{
    try
    {
        string fullPath = Path.Combine(_environment.WebRootPath, tempFilePath.TrimStart('/'));
        if (!System.IO.File.Exists(fullPath))
        {
            return NotFound();
        }
        byte[] fileBytes = System.IO.File.ReadAllBytes(fullPath);
        System.IO.File.Delete(fullPath);
        string fileName = !string.IsNullOrEmpty(userFileName) ? userFileName : "ExportedDocument.docx";
        return File(fileBytes, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", fileName);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error downloading file");
        return BadRequest("An error occurred while downloading the file.");
    }
}
[HttpGet]
public IActionResult DownloadFile(string tempFilePath, string userFileName)
{
    try
    {
        string fullPath = Path.Combine(_environment.WebRootPath, tempFilePath.TrimStart('/'));
        if (!System.IO.File.Exists(fullPath))
        {
            return NotFound();
        }
        byte[] fileBytes = System.IO.File.ReadAllBytes(fullPath);
        System.IO.File.Delete(fullPath);
        string fileName = !string.IsNullOrEmpty(userFileName) ? userFileName : "ExportedDocument.docx";
        return File(fileBytes, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", fileName);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error downloading file");
        return BadRequest("An error occurred while downloading the file.");
    }
}
<HttpGet>
Public Function DownloadFile(ByVal tempFilePath As String, ByVal userFileName As String) As IActionResult
	Try
		Dim fullPath As String = Path.Combine(_environment.WebRootPath, tempFilePath.TrimStart("/"c))
		If Not System.IO.File.Exists(fullPath) Then
			Return NotFound()
		End If
		Dim fileBytes() As Byte = System.IO.File.ReadAllBytes(fullPath)
		System.IO.File.Delete(fullPath)
		Dim fileName As String = If(Not String.IsNullOrEmpty(userFileName), userFileName, "ExportedDocument.docx")
		Return File(fileBytes, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", fileName)
	Catch ex As Exception
		_logger.LogError(ex, "Error downloading file")
		Return BadRequest("An error occurred while downloading the file.")
	End Try
End Function
VB   C#

此方法檢索由 ExportWordDocument 創建的臨時文件,將其內容讀入字節數組,然後刪除該臨時文件。它使用提供的用戶文件名,或如果未提供則使用默認名稱。 然後該方法將文件內容作為可下載的 Word 文檔返回。 如果檔案未找到或發生錯誤,則會返回適當的 HTTP 回應。

4.4 增強應用程式的視覺設計

為了改善我們的Word文件處理器的整體外觀和感受,我們直接在 _Layout.cshtml 文件中添加了自定義CSS。讓我們來檢查一下我們實施的樣式設計:

<style>
    :root {
        --primary-color: #3498db;
        --text-color: #333;
        --bg-color: #f8f9fa;
        --nav-bg: #fff;
        --nav-text: #2c3e50;
        --nav-hover: #3498db;
    }
    body {
        font-family: 'Segoe UI', sans-serif;
        background-color: var(--bg-color);
        color: var(--text-color);
        line-height: 1.6;
    }
    .navbar { background-color: var(--nav-bg); }
    .navbar-brand {
        font-size: 1.5rem;
        font-weight: 700;
        color: var(--primary-color);
        margin-right: 2rem;
    }
    .navbar-nav { margin-left: auto; }
    .navbar-nav .nav-item { margin-left: 1rem; }
    .navbar-nav .nav-link {
        color: var(--nav-text);
        font-weight: 500;
        transition: all 0.3s ease;
        padding: 0.5rem 1rem;
        border-radius: 4px;
    }
    .navbar-nav .nav-link:hover, .navbar-nav .nav-link.active {
        color: var(--primary-color);
        background-color: rgba(52, 152, 219, 0.1);
    }
    .navbar-nav .nav-link i {
        margin-right: 0.5rem;
        font-size: 1.1em;
    }
    .centered-container {
        max-width: 800px;
        margin: 0 auto;
        padding: 2rem;
    }
    .footer {
        background-color: var(--nav-bg);
        border-top: 1px solid #ecf0f1;
        font-size: 0.9em;
        color: var(--nav-text);
    }
    .footer a {
        color: var(--primary-color);
        text-decoration: none;
        transition: color 0.3s ease;
    }
    .footer a:hover { color: var(--nav-hover); }
    @@media (max-width: 576px) {
        .navbar-nav {
            margin-left: 0;
            margin-top: 1rem;
        }
        .navbar-nav .nav-item {
            margin-left: 0;
            margin-bottom: 0.5rem;
        }
    }
</style>
<style>
    :root {
        --primary-color: #3498db;
        --text-color: #333;
        --bg-color: #f8f9fa;
        --nav-bg: #fff;
        --nav-text: #2c3e50;
        --nav-hover: #3498db;
    }
    body {
        font-family: 'Segoe UI', sans-serif;
        background-color: var(--bg-color);
        color: var(--text-color);
        line-height: 1.6;
    }
    .navbar { background-color: var(--nav-bg); }
    .navbar-brand {
        font-size: 1.5rem;
        font-weight: 700;
        color: var(--primary-color);
        margin-right: 2rem;
    }
    .navbar-nav { margin-left: auto; }
    .navbar-nav .nav-item { margin-left: 1rem; }
    .navbar-nav .nav-link {
        color: var(--nav-text);
        font-weight: 500;
        transition: all 0.3s ease;
        padding: 0.5rem 1rem;
        border-radius: 4px;
    }
    .navbar-nav .nav-link:hover, .navbar-nav .nav-link.active {
        color: var(--primary-color);
        background-color: rgba(52, 152, 219, 0.1);
    }
    .navbar-nav .nav-link i {
        margin-right: 0.5rem;
        font-size: 1.1em;
    }
    .centered-container {
        max-width: 800px;
        margin: 0 auto;
        padding: 2rem;
    }
    .footer {
        background-color: var(--nav-bg);
        border-top: 1px solid #ecf0f1;
        font-size: 0.9em;
        color: var(--nav-text);
    }
    .footer a {
        color: var(--primary-color);
        text-decoration: none;
        transition: color 0.3s ease;
    }
    .footer a:hover { color: var(--nav-hover); }
    @@media (max-width: 576px) {
        .navbar-nav {
            margin-left: 0;
            margin-top: 1rem;
        }
        .navbar-nav .nav-item {
            margin-left: 0;
            margin-bottom: 0.5rem;
        }
    }
</style>
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'(Of style) :root
'{
'		--primary-color: #3498db;
'		--text-color: #333;
'		--bg-color: #f8f9fa;
'		--nav-bg: #fff;
'		--nav-text: #2c3e50;
'		--nav-hover: #3498db;
'	}
	body
	If True Then
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'		font-family: 'Segoe UI', sans-serif; background-color: var(--bg-color); color: var(--text-color); line-height: 1.6; } .navbar { background-color: var(--nav-bg); } .navbar-brand { font-size: 1.5rem; font-weight: 700; color: var(--primary-color); margin-right: 2rem; } .navbar-nav { margin-left: auto; } .navbar-nav.nav-item { margin-left: 1rem; } .navbar-nav.nav-link { color: var(--nav-text); font-weight: 500; transition: all 0.3s ease; padding: 0.5rem 1rem; border-radius: 4px; } .navbar-nav.nav-link:hover, .navbar-nav.nav-link.active { color: var(--primary-color); background-color: rgba(52, 152, 219, 0.1); } .navbar-nav.nav-link i { margin-right: 0.5rem; font-size: 1.1em; } .centered-container { max-width: 800px; margin: 0 auto; padding: 2rem; } .footer { background-color: var(--nav-bg); border-top: 1px solid #ecf0f1; font-size: 0.9em; color: var(--nav-text); } .footer a { color: var(--primary-color); text-decoration: none; transition: color 0.3s ease; } .footer a:hover { color: var(--nav-hover); } @@media(max-width: 576px) { .navbar-nav { margin-left: 0; margin-top: 1rem; } .navbar-nav.nav-item { margin-left: 0; margin-bottom: 0.5rem; } } </style>
VB   C#

此 CSS 區塊定義了我們應用程式的色彩方案和佈局。 我們正在使用 CSS 變數(自定義屬性)在整個應用程式中創建一致的顏色調色板。樣式針對包括正文、導航欄和頁腳在內的各種元素,以確保設計統一。 我們已經設置了具有乾淨現代外觀的導航欄,其特點是懸停效果和圖示整合。 W

雖然我們的應用程式目前專注於 Word 文件,但我們可以使用IronPDF以支持 PDF 文件來擴展其功能,涵蓋更廣泛的文件類型。系統可以擴展為允許用戶除了當前的 Word 格式選項外,還能將其文件匯出為 PDF 文件。

5. 執行應用程式

讓我們先運行 WordDocumentProcessor 應用程式。 正如我們在圖片中所見,應用程式已經成功載入於瀏覽器中。 介面簡潔且使用者友好,頂部的導航欄顯示 "首頁" 和 "匯出" 選項。 主要內容區顯示標題「Word Document Processor」以及簡短描述:「輕鬆上傳和處理您的 Word 文件。」

ASP .NET Core 匯入和匯出 Word 文件:圖 3

現在,我們來嘗試匯入文件。 在圖片中,我們可以看到我們選擇了一個名為「Honey research synopsis.docx」的檔案。 檔案名稱顯示在上傳區域,取代了「選擇檔案」按鈕。 我們現在準備好上傳和處理此文件。

ASP .NET Core 導入和導出 Word 文件:圖 4

點擊「上傳和處理」後,應用程式會處理文件並顯示其內容。 “文件內容”部分現在顯示上傳文件的開頭部分。 我們可以看到標題 "都市地區的養蜂技術和蜂蜜生產質量",接著是一個摘要。 這表明我們的應用程式已成功讀取並顯示了 Word 文件的內容。

ASP .NET Core 匯入和匯出 Word 檔案:圖 5

最後,讓我們測試匯出功能。 在圖片中,我們看到當我們點擊導航欄中的“導出”按鈕時出現的提示。 提示要求我們「輸入文件的名字」(無擴展)"." 預設名稱「ExportedDocument」已預先填入,但我們可以根據需要更改它。 此提示允許我們在下載之前自訂導出文件的名稱。

ASP .NET Core 匯入和匯出Word文件:圖6

單擊“確定”後,應用程式將生成一個具有指定名稱的新 Word 文件並開始下載過程。 此匯出的文件包含我們在應用程式中處理的內容或所做的任何修改。

ASP .NET Core 匯入與匯出 Word 檔案:圖 7

在整個過程中,我們可以看到應用程序運行如預期。 我們可以使用此應用程式輕鬆導入 Word 文件、創建文件並導出它們。 用戶介面直觀且具回應性。

結論

總之,我們的 WordDocumentProcessor 應用程序成功展示了在 ASP.NET Core 網頁應用中整合 Word 文檔處理的強大功能和靈活性。 通過利用IronWord庫,我們創建了一個穩健的解決方案,使導入、顯示和導出Word文檔變得輕鬆。 此應用程式作為更複雜的文件管理系統或報告生成器的堅實基礎。 對於有興趣探索 IronWord 功能的開發人員,該函式庫提供一個免費試用. 試用期結束後,授權費用自 $749 起,是一個對於需要在其網絡應用程式中進行高級 Word 文件處理功能的企業而言,具成本效益的解決方案。

下一個 >
VS 2022 程式化建立新的 Word 文件(教程)