ASP.NET Core 匯入和匯出 Word 文件
本指南探討如何匯入現有的 Word 文件、顯示其內容以及使用IronWord 庫從頭開始建立文件。 完成本教學後,您將建立一個能夠執行以下操作的ASP.NET Core Web 應用程式:
- 上傳和閱讀 Word 文件
- 將這些文件的內容顯示在文字方塊中
- 匯出 Docx 文件
對於需要將 Word 文件處理整合到其 Web 應用程式中的開發人員來說,無論是文件管理系統、報表產生器,或是任何其他涉及 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 項目
- 開啟 Visual Studio 2019 或更高版本。
- 點選"建立新項目"。
- 搜尋"ASP.NET Core Web 應用程式"並選擇它。
- 點選"下一步"。
- 將你的專案命名為"WordDocumentProcessor"(或你喜歡的任何名稱)。
- 選擇 .NET Framework 和專案位置,然後按一下"建立"。
2.2 安裝 IronWord NuGet 套件
現在我們的專案已經設定好了,讓我們加入 IronWord 庫:
- 在解決方案資源管理器中以滑鼠右鍵按一下您的專案。
- 選擇"管理 NuGet 套件"。
- 在"瀏覽"標籤中,搜尋"IronWord"。
- 尋找官方的 IronWord 軟體包。
- 點擊"安裝"將其新增至您的專案。
2.3 更新現有控制器與視圖
讓我們更新現有架構,使其包含文件處理功能:
- 我們將使用 Controllers 資料夾中現有的HomeController.cs檔案來實作文件處理邏輯。
- 我們將更新 Views/Home 資料夾中現有的Index.cshtml視圖,使其包含文件上傳和顯示功能。
現在我們的專案已經設定完畢,IronWord 軟體套件也已安裝完畢,我們可以開始實作文件匯入和匯出功能了。 我們將向 HomeController 新增方法,並修改 Index 視圖以處理這些功能。 下一節,我們將重點介紹如何匯入 Word 文件並顯示其內容,利用我們現有的控制器和視圖結構。
3. 導入 Word 文件
在本節中,我們將探討如何在 ASP.NET MVC 應用程式中實現導入和處理 Word 文件的功能。 我們將介紹使用者介面設計和後端控制器邏輯。
3.1 使用者介面設計
導入 Word 文件的使用者介面設計直覺且美觀。 讓我們來分解一下使用者介面的關鍵組成部分:
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>這段程式碼創建了一個視覺上吸引人的上傳區域,其中包含文件圖示、隱藏的文件輸入框和用作文件選擇按鈕的樣式標籤。 它還包含有關可接受的文件類型的信息以及用於啟動上傳和處理的按鈕。
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>本部分提供了一個可捲動區域,用於顯示已處理文件的內容。
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." });
}
}此方法執行以下任務:
- 驗證上傳的文件,確保其文件格式正確(DOC 或 DOCX)。
- 使用 IronWord 庫處理文件。 3.以 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();
}這種方法確保文件內容以 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';
});
});這段 JavaScript 程式碼處理檔案上傳過程,將檔案傳送到伺服器進行處理,並使用處理後的內容或錯誤訊息更新 UI。
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>這段 CSS 程式碼採用淺色調方案,營造出簡潔現代的外觀。 上傳區域採用白色背景,並帶有微妙的陰影效果,而內容區域則採用可捲動設計,背景為淺灰色。 使用 border-radius 和 box-shadow 屬性可以為介面元素增加深度和視覺趣味性。
4. 匯出 Word 文件
為了不斷改進我們的 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>我們使用 Font Awesome 作為圖標,所以請確保我們的 CSS 連結已包含在我們的程式碼中。
部分。 這段程式碼會在導覽列中新增一個"匯出"連結。 它使用 Font Awesome 作為圖標,點擊時調用exportDocument()函數。 href="#"並回傳 false 會阻止連結的預設行為。4.2 實作客戶端導出邏輯
現在,讓我們加入處理導出過程的 JavaScript 函數。 在我們的_Layout.cshtml檔案底部,就在結束語句之前







