ASP.NET Coreでワードファイルをインポート&エクスポートする
このガイドでは、既存のWordドキュメントをインポートし、その内容を表示し、IronWordライブラリを使用して初めからドキュメントを作成する方法を探ります。 このチュートリアルの終わりまでに、次のことができるASP.NET Coreウェブアプリケーションを作成します。
- Wordドキュメントのアップロードと読み取り
- これらのドキュメントの内容をテキストボックスに表示
- Docxファイルのエクスポート
このプロジェクトは、ドキュメント管理システム、レポートジェネレーター、またはMicrosoft Wordファイルを含むその他のシナリオのいずれかにおいて、ウェブアプリケーションにWordドキュメント処理を統合する必要がある開発者に最適です。
前提条件
このチュートリアルを進めるには、次を持っているべきです:
- C#およびASP.NET Coreの基本知識
- Visual Studio 2019以降がインストールされている(または、C#エクステンションを使用したVisual Studio Codeを使用できます)
- .NET Core SDK 3.1またはそれ以降
これらの技術に詳しくなくても心配しないでください - 我々はプロセスの各ステップを案内します!
IronWordとは何ですか?
IronWordは、開発者がプログラム的にMicrosoft Wordドキュメントを読み、操作し、作成できる.NETライブラリです。 高レベルの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 Application"を検索して選択します。
- "次へ"をクリックします。
- プロジェクトに"WordDocumentProcessor"(またはお好みの名前)を名付けます。
- .NETフレームワークとプロジェクトの場所を選択し、"作成"をクリックします。
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ドキュメントをインポートするためのユーザーインターフェースは、直感的で視覚的に魅力的なように設計されています。 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>このコードは、ファイルアイコン、隠しファイル入力、およびファイル選択ボタンとして機能するスタイル付きラベルを持つ視覚的に魅力的なアップロードエリアを作成します。 受け入れられるファイルタイプに関する情報と、アップロードと処理を開始するボタンも含まれています。
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." });
}
}<HttpPost>
Public Function UploadAndProcess(ByVal file As IFormFile) As IActionResult
If file Is Nothing OrElse 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このメソッドは次のタスクを実行します。
- アップロードされたファイルの形式が正しいか(DOCまたはDOCX)確認します。
- IronWordライブラリを用いてドキュメントを処理します。
- フォーマット済みの内容を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このメソッドは、各行を段落タグでラップし、空行を保持してドキュメントコンテンツを正しく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は、明るいカラースキームでクリーンで現代的な外観を作成します。 アップロードエリアには、白い背景と微妙な影の効果があり、コンテンツエリアはスクロール可能なデザインでライトグレーの背景を持っています。 ボーダー半径およびボックスシャドウのプロパティを使用して、インターフェイス要素に深みと視覚的な興味を追加します。
4. Wordドキュメントのエクスポート
Word Document Processorをさらに強化して、ドキュメントをエクスポートできるようにしましょう。 この機能により、ユーザーはアプリケーションから新しい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="#"とreturn falseを使用しています。4.2 クライアントサイドのエクスポートロジックの実装
次に、エクスポートプロセスを処理するJavaScript関数を追加しましょう。 _Layout.cshtmlファイルの下部、閉じる













