[C#] CKEditor 輸出成Word文件(包含圖案上傳)
專案需求,必須要將CKEditor 的HTML 結果輸出成Word .docx 檔案
就順便筆記一下..
您當然要有些關於CKEditor 的基本知識
教學參考:
http://blog.kkbruce.net/2010/08/aspnet-ckeditor-ckfinder.html#.UawjNUCcNoE
http://www.dotblogs.com.tw/eaglewolf/archive/2012/01/19/66546.aspx
當然我這邊就不贅述,你在下方直接download sample source code 也是可以直接使用..
首先,我們就先將CKEditor 下載或是透過Nuget 取得..
再來我們修改 /Scripts/ckeditor/config.js
讓圖片上傳能夠正常..
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.editorConfig = function( config )
{
config.filebrowserImageUploadUrl = "/fileupload.aspx";
};
其中我們讓檔案上傳的處理路徑指到跟執行目錄下 fileupload.aspx
之後我們來撰寫關於 fileupload.aspx 的部分..
fileupload.apsx 關於 .aspx 得部分只需要留下第一行其他都要刪除
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="fileupload.aspx.cs" Inherits="SimpleConvetCKEditorHTMLToOpenXML.fileupload" %>
fileuploas.aspx.cs 的部分:
using System;
using System.IO;
using System.Web;
namespace SimpleConvetCKEditorHTMLToOpenXML
{
public partial class fileupload : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
HttpPostedFile uploads = Context.Request.Files["upload"];
string ckediotfuncnum = Context.Request["CKEditorFuncNum"];
var t = Guid.NewGuid().ToString("N");
//如果暫存資料夾不在就建立
if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + "uploaded\\"))
{
Directory.GetCreationTime(AppDomain.CurrentDomain.BaseDirectory + "uploaded\\");
}
//判斷圖片是否為.png or .jpg
//當然這方法並非很好
//建議作法依然要打打開圖片做檢查會比較安全
if (Path.GetExtension(uploads.FileName).ToLower() == ".jpg" || Path.GetExtension(uploads.FileName).ToLower() == ".png")
{
string url = "/uploaded/" + t + Path.GetExtension(uploads.FileName);
File.WriteAllBytes(AppDomain.CurrentDomain.BaseDirectory + "uploaded\\" + t + Path.GetExtension(uploads.FileName), StreamToBytes(uploads.InputStream));
Response.Write("<script>window.parent.CKEDITOR.tools.callFunction(" + ckediotfuncnum + ",\"" + url + "\");</script>");
}
else
{
Response.Write("<script>alert('上傳格式錯誤');</script>");
Response.Write("<script>window.parent.CKEDITOR.tools.callFunction(" + ckediotfuncnum + ");</script>");
}
}
/// <summary>
/// 將Stream 轉成 Byte[]
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
private byte[] StreamToBytes(Stream stream)
{
stream.Position = 0;
var buffer = new byte[stream.Length];
for (int totalBytesCopied = 0; totalBytesCopied < stream.Length; )
totalBytesCopied += stream.Read(buffer, totalBytesCopied, Convert.ToInt32(stream.Length) - totalBytesCopied);
return buffer;
}
}
}
再來我們看一下關於 轉成Word 檔的部分..
首先,你得先去下載必須的library .
Open XML SDK 2.0 for Microsoft Office
安裝後我電腦是Windows 8 位置會大概在..
再來去下載一個方便的工具HtmlToOpenXML
接下來,就可以開始寫程式…
using System;
using System.IO;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using NotesFor.HtmlToOpenXml;
namespace SimpleConvetCKEditorHTMLToOpenXML
{
public partial class demo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnConvertToWord_Click(object sender, EventArgs e)
{
var fileName = Guid.NewGuid().ToString("N") + ".docx";
var filePathName = AppDomain.CurrentDomain.BaseDirectory + "words\\" +fileName;
var html = CKEditorControl1.Text;
using (MemoryStream generatedDocument = new MemoryStream())
{
using (WordprocessingDocument package = WordprocessingDocument.Create(generatedDocument, WordprocessingDocumentType.Document))
{
MainDocumentPart mainPart = package.MainDocumentPart;
if (mainPart == null)
{
mainPart = package.AddMainDocumentPart();
new Document(new Body()).Save(mainPart);
}
HtmlConverter converter = new HtmlConverter(mainPart);
Body body = mainPart.Document.Body;
//如果有插入圖片,這一行很重要
converter.BaseImageUrl = new Uri("http://localhost:16777");
var paragraphs = converter.Parse(html);
for (int i = 0; i < paragraphs.Count; i++)
{
body.Append(paragraphs[i]);
}
mainPart.Document.Save();
}
File.WriteAllBytes(filePathName, generatedDocument.ToArray());
ltlMessage.Text = "已輸出至" + "words\\" + fileName;
}
}
}
}
如果,有遇到
"The type 'System.IO.Packaging.Package' is defined in an assembly that is not referenced. You must add a reference to assembly 'WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
結果:
Source Code 下載 :https://github.com/donma/ConvertCKEditorToWordOpenXML