C#實(shí)現(xiàn)將Word轉(zhuǎn)化分享為電子期刊
需求
曾經(jīng)的一個(gè)項(xiàng)目,要求實(shí)現(xiàn)制作電子期刊定期發(fā)送給企業(yè)進(jìn)行閱讀,基本的需求如下:
1、由編輯人員使用 Microsoft Word 編輯期刊內(nèi)容,上傳到系統(tǒng),生成PDF文件。
2、將生成的PDF文件轉(zhuǎn)化為JPEG文件。
3、將JPEG文件制作目錄結(jié)構(gòu),并生成電子書模式。
方案分析
分析了一下需求,制作了初步的實(shí)現(xiàn)方案,主要有以下幾點(diǎn)分析:
1、Microsoft Word 仍然是目前比較常用和廣泛使用的應(yīng)用程序,適用于各類人群,他們只需要編寫好自己的文稿即可(包括文字、圖片、排版),所以可以作為實(shí)現(xiàn)電子書的基礎(chǔ)。
2、較高版本的 Word 如2016、2019及以上,可以提供另存為PDF的能力,利用API可以將DOCX另存為PDF文件,為進(jìn)一步生成JPEG圖片提供基礎(chǔ)。
3、利用改造過(guò)的 turn.js 實(shí)現(xiàn)電子書及翻頁(yè)效果。
相關(guān)庫(kù)引入
實(shí)現(xiàn)功能要引入相關(guān)庫(kù),包括 PdfiumViewer.dll 和 turn.js 相關(guān)包,另外,在服務(wù)器端您需要安裝 Microsoft Word 2016 或以上版本。
關(guān)鍵代碼
Word 轉(zhuǎn) Pdf
在操作界面,上傳WORD文件,通過(guò)API將其另存為PDF文件。
示例代碼如下:
public string WordToPdf(string _filename)
{
string resultReport=""; //調(diào)試信息
Object Nothing =System.Reflection.Missing.Value;
//在上傳目錄下一定要?jiǎng)?chuàng)建一個(gè)tempbfile目錄用于存儲(chǔ)臨時(shí)文件
string _file="",_path=Path.GetDirectoryName(_filename)+"\\tempbfile\\",_ext="";
_file=Path.GetFileNameWithoutExtension(_filename);
_ext=Path.GetExtension(_filename);
string _validfilename=Guid.NewGuid().ToString()+_ext;
string _lastfile=_path+_validfilename;
string _pdfFile = _path + Guid.NewGuid().ToString() + ".pdf";
File.Copy(_filename,_lastfile,true);
if(!File.Exists(_lastfile))
{
resultReport += "create " + _lastfile + " fail.<br>";
return "";
}
//取得Word文件保存路徑
object filename=_lastfile;
//創(chuàng)建一個(gè)名為WordApp的組件對(duì)象
Word.Application WordApp=new Word.Application();
//創(chuàng)建一個(gè)名為WordDoc的文檔對(duì)象
WordApp.DisplayAlerts=Word.WdAlertLevel.wdAlertsNone;
Word.Document WordDoc=WordApp.Documents.Open(ref filename,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing);
WordDoc.SpellingChecked = false;
WordDoc.ShowSpellingErrors = false;
string pdfFilename = "";
//導(dǎo)出到pdf文件
WordDoc.ExportAsFixedFormat(_pdfFile, Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF,false,Word.WdExportOptimizeFor.wdExportOptimizeForPrint,
wdExportRange,pagefrom,pageto,Word.WdExportItem.wdExportDocumentContent,false,true,Word.WdExportCreateBookmarks.wdExportCreateNoBookmarks,
true,true,false, ref Nothing);
if (File.Exists(_pdfFile))
{
pdfFilename = _pdfFile;
}
WordDoc.Close(ref Nothing, ref Nothing, ref Nothing);
//關(guān)閉WordApp組件對(duì)象
WordApp.Quit(ref Nothing, ref Nothing, ref Nothing);
return pdfFilename;
}Pdf 轉(zhuǎn)批量 Jpeg
生成pdf文件后,我們需要將其轉(zhuǎn)化到指定目錄下,批量生成JPEG圖片,以備客戶端JS進(jìn)行調(diào)用。
方法介紹:
public void PdfToImage(string pdfInputPath, string imageOutputPath,string imageName)
//參數(shù)1:PDF文件路徑,參數(shù)2:輸出圖片的路徑,參數(shù)3:圖片文件名的前綴,比如輸入Img,則會(huì)輸出Img_001.jpg、Img_002.jpg。。。以此類推。
示例代碼如下:
//參數(shù)1:PDF文件路徑,參數(shù)2:輸出圖片的路徑,參數(shù)3:圖片文件名的前綴,比如輸入Img,則會(huì)輸出Img_001.jpg、Img_002.jpg以此類推
public void PdfToImage(string pdfInputPath, string imageOutputPath,string imageName)
{
// PdfRenderFlags.Annotations 改成 PdfRenderFlags.CorrectFromDpi DPI值設(shè)置成600 即可高清圖像
if (Directory.Exists(imageOutputPath) == false)
{
Directory.CreateDirectory(imageOutputPath);
}
var pdf = PdfiumViewer.PdfDocument.Load(pdfInputPath);
var pdfpage = pdf.PageCount;
var pagesizes = pdf.PageSizes;
if (pdfpage == 0)
{
pdf.Dispose();
return;
}
var document = PdfiumViewer.PdfDocument.Load(pdfInputPath);
for (int i = 1; i <= pdfpage; i++)
{
Size size = new Size();
size.Height = (int)pagesizes[(i - 1)].Height;
size.Width = (int)pagesizes[(i - 1)].Width;
//可以把".jpg"寫成其他形式
string tmpfile = imageOutputPath + imageName + "_" + i.ToString().PadLeft(3, '0') + ".jpg";
var stream = new FileStream(tmpfile, FileMode.Create);
var image = document.Render(i - 1, size.Width, size.Height, 120, 120, PdfRenderFlags.CorrectFromDpi);
image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
stream.Close();
}
document.Dispose();
pdf.Dispose();
}Jpeg 轉(zhuǎn)為電子書
根據(jù) turn.js 的格式要求,我們?cè)诜?wù)端 Page_Load 事件里生成一個(gè) ViewState,直接輸出到客戶端,ViewState["result"] 是我們要輸出的變量,我們對(duì)指定的 jpgTmpPath 變量目錄進(jìn)行遍歷,符合jpeg或jpg擴(kuò)展名的文件則進(jìn)行記錄。
服務(wù)端示例代碼如下:
protected void Page_Load(object sender, EventArgs e)
{
ViewState["result"] = ""; //關(guān)鍵的viewsate,用于存儲(chǔ)JPEG地址數(shù)組格式
string _cid=Request.QueryString["cid"];
if ( _cid!= null)
{
string result = "";
string jpgTmpPath = Request.PhysicalApplicationPath + "\\ebook\\" + _cid + "\\";
if (Directory.Exists(jpgTmpPath))
{
string[] allfs = System.IO.Directory.GetFiles(jpgTmpPath);
for (int i = 0; i < allfs.Length; i++)
{
string jpgfile = allfs[i].ToLower();
string filename = System.IO.Path.GetFileName(jpgfile);
if (jpgfile.IndexOf(".jpg") == -1 && jpgfile.IndexOf(".jpeg") == -1)
{
continue;
}
result += "\"../../ebook/" + _cid + "/" + filename + "\",\r\n";
}
ViewState["result"] = result;
}
}
if (ViewState["result"].ToString() == "")
{
Response.Write("沒(méi)有預(yù)覽資源");
Response.End();
}
}中間UI代碼引用示例:
<head runat="server">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache,no-store,must-revalidate"/>
<meta http-equiv="Expires" content="0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<meta name="format-detection" content="telephone=no">
<meta name="apple-mobile-web-app-capable" content="yes"/>
<title>電子期刊預(yù)覽</title>
<link rel="stylesheet" type="text/css" href="css/basic.css" rel="external nofollow" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/modernizr.2.5.3.min.js"></script>
</head>
<div class="shade">
<div class="sk-fading-circle">
<div class="sk-circle1 sk-circle"></div>
<div class="sk-circle2 sk-circle"></div>
<div class="sk-circle3 sk-circle"></div>
<div class="sk-circle4 sk-circle"></div>
<div class="sk-circle5 sk-circle"></div>
<div class="sk-circle6 sk-circle"></div>
<div class="sk-circle7 sk-circle"></div>
<div class="sk-circle8 sk-circle"></div>
<div class="sk-circle9 sk-circle"></div>
<div class="sk-circle10 sk-circle"></div>
<div class="sk-circle11 sk-circle"></div>
<div class="sk-circle12 sk-circle"></div>
</div>
<div class="number"></div>
</div>
<div class="flipbook-viewport" style="display:none;">
<div class="previousPage"></div>
<div class="nextPage"></div>
<div class="return"></div>
<img class="btnImg" src="./image/btn.gif" style="display: none"/>
<div class="container">
<div class="flipbook">
</div>
<div class="pagenumber">
</div>
</div>
</div> 客戶端腳本:
在客戶端我們接收來(lái)自 ViewState["result"] 的變量值,實(shí)現(xiàn)電子書的效果:
<script type="text/javascript">
var loading_img_url = [
<%=ViewState["result"]%>
];
</script>
<script type="text/javascript" src="js/main.js"></script>
<script>
//自定義彈出層
(function ($) {
//ios confirm box
jQuery.fn.confirm = function (title, option, okCall, cancelCall) {
var defaults = {
title: null, //what text
cancelText: '取消', //the cancel btn text
okText: '確定' //the ok btn text
};
if (undefined === option) {
option = {};
}
if ('function' != typeof okCall) {
okCall = $.noop;
}
if ('function' != typeof cancelCall) {
cancelCall = $.noop;
}
var o = $.extend(defaults, option, { title: title, okCall: okCall, cancelCall: cancelCall });
var $dom = $(this);
var dom = $('<div class="g-plugin-confirm">');
var dom1 = $('<div>').appendTo(dom);
var dom_content = $('<div>').html(o.title).appendTo(dom1);
var dom_btn = $('<div>').appendTo(dom1);
var btn_cancel = $('<a href="#" rel="external nofollow" rel="external nofollow" ></a>').html(o.cancelText).appendTo(dom_btn);
var btn_ok = $('<a href="#" rel="external nofollow" rel="external nofollow" ></a>').html(o.okText).appendTo(dom_btn);
btn_cancel.on('click', function (e) {
o.cancelCall();
dom.remove();
e.preventDefault();
});
btn_ok.on('click', function (e) {
o.okCall();
dom.remove();
e.preventDefault();
});
dom.appendTo($('body'));
return $dom;
};
})(jQuery);
if ($(window).width() > 1024 && $(window).height() > 700) {
//上一頁(yè)
$(".previousPage").bind("click", function () {
var pageCount = $(".flipbook").turn("pages"); //總頁(yè)數(shù)
var currentPage = $(".flipbook").turn("page"); //當(dāng)前頁(yè)
if (currentPage > 2) {
$(".flipbook").turn('page', currentPage - 2);
} else if (currentPage == 2) {
$(".flipbook").turn('page', currentPage - 1);
}
});
// 下一頁(yè)
$(".nextPage").bind("click", function () {
var pageCount = $(".flipbook").turn("pages"); //總頁(yè)數(shù)
var currentPage = $(".flipbook").turn("page"); //當(dāng)前頁(yè)
if (currentPage < pageCount - 1) {
$(".flipbook").turn('page', currentPage + 2);
} else if (currentPage == pageCount - 1) {
$(".flipbook").turn('page', currentPage + 1);
}
});
} else {
//上一頁(yè)
$(".previousPage").bind("click", function () {
var pageCount = $(".flipbook").turn("pages"); //總頁(yè)數(shù)
var currentPage = $(".flipbook").turn("page"); //當(dāng)前頁(yè)
if (currentPage >= 2) {
$(".flipbook").turn('page', currentPage - 1);
} else {
}
});
// 下一頁(yè)
$(".nextPage").bind("click", function () {
var pageCount = $(".flipbook").turn("pages"); //總頁(yè)數(shù)
var currentPage = $(".flipbook").turn("page"); //當(dāng)前頁(yè)
if (currentPage <= pageCount) {
$(".flipbook").turn('page', currentPage + 1);
} else {
}
});
}
//返回到目錄頁(yè)
$(".return").bind("click", function () {
$(document).confirm('您確定要返回首頁(yè)嗎?', {}, function () {
$(".flipbook").turn('page', 1); //跳轉(zhuǎn)頁(yè)數(shù)
}, function () {
});
});
function gotopage(pageindex) {
$(".flipbook").turn('page',pageindex);
}
</script>實(shí)現(xiàn)效果演示

小結(jié)
以上提供的代碼僅供參考,turn.js 我花了一些時(shí)間進(jìn)行了改造,我們也可以根據(jù)自己的需要對(duì)樣式、控制進(jìn)行改造。其它的一些細(xì)節(jié)我們可以進(jìn)一步調(diào)整,如圖片生成質(zhì)量、權(quán)限控制等。
另外,還可以實(shí)現(xiàn)下載、評(píng)價(jià)、點(diǎn)贊、收藏等其它功能,這里就不再一一介紹。
以上就是C#實(shí)現(xiàn)將Word轉(zhuǎn)化分享為電子期刊的詳細(xì)內(nèi)容,更多關(guān)于C# Word轉(zhuǎn)化為電子期刊的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#修改IIS站點(diǎn)framework版本號(hào)的方法
這篇文章主要介紹了C#修改IIS站點(diǎn)framework版本號(hào)的方法,涉及C#調(diào)用使用ASP.NET IIS注冊(cè)工具Aspnet_regiis.exe進(jìn)行IIS站點(diǎn)framework版本號(hào)修改的方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10
C# 實(shí)現(xiàn)PPT 每一頁(yè)轉(zhuǎn)成圖片過(guò)程解析
這篇文章主要介紹了C# 實(shí)現(xiàn)PPT 每一頁(yè)轉(zhuǎn)成圖片過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
.NET/C#實(shí)現(xiàn)識(shí)別用戶訪問(wèn)設(shè)備的方法
這篇文章主要介紹了.NET/C#實(shí)現(xiàn)識(shí)別用戶訪問(wèn)設(shè)備的方法,結(jié)合實(shí)例形式分析了C#識(shí)別用戶訪問(wèn)設(shè)備的操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02
C#開(kāi)發(fā)Android百度地圖手機(jī)應(yīng)用程序(多地圖展示)
這篇文章主要介紹了C#開(kāi)發(fā)Android百度地圖手機(jī)應(yīng)用程序(多地圖展示)的相關(guān)資料,需要的朋友可以參考下2016-02-02
Winform學(xué)生信息管理系統(tǒng)各子窗體剖析(3)
這篇文章主要針對(duì)Winform學(xué)生信息管理系統(tǒng)各子窗體進(jìn)行剖析,感興趣的小伙伴們可以參考一下2016-05-05
C#?PictureBox控件方法參數(shù)及圖片刪除重命名上傳詳解
這篇文章主要為大家介紹了C#?PictureBox控件方法參數(shù)及圖片刪除重命名上傳示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08

