C# 将 Word 转化分享为电子期刊

 

目录

需求

方案分析

相关库引入

关键代码

Word 转 Pdf

Pdf 转批量 Jpeg

Jpeg 转为电子书

实现效果演示

小结


需求

曾经的一个项目,要求实现制作电子期刊定期发送给企业进行阅读,基本的需求如下:

1、由编辑人员使用 Microsoft Word 编辑期刊内容,上传到系统,生成PDF文件。

2、将生成的PDF文件转化为JPEG文件。

3、将JPEG文件制作目录结构,并生成电子书模式。

方案分析

分析了一下需求,制作了初步的实现方案,主要有以下几点分析:

1、Microsoft Word 仍然是目前比较常用和广泛使用的应用程序,适用于各类人群,他们只需要编写好自己的文稿即可(包括文字、图片、排版),所以可以作为实现电子书的基础。

2、较高版本的 Word 如2016、2019及以上,可以提供另存为PDF的能力,利用API可以将DOCX另存为PDF文件,为进一步生成JPEG图片提供基础。

3、利用改造过的 turn.js 实现电子书及翻页效果。 

相关库引入

实现功能要引入相关库,包括 PdfiumViewer.dll 和 turn.js 相关包,完整下载链接请访问:

https://download.csdn.net/download/michaelline/88647689

另外,在服务器端您需要安装 Microsoft Word 2016 或以上版本。

关键代码

Word 转 Pdf

在操作界面,上传WORD文件,通过API将其另存为PDF文件。

示例代码如下:

        public string WordToPdf(string _filename){string resultReport=""; //调试信息Object Nothing =System.Reflection.Missing.Value;
//在上传目录下一定要创建一个tempbfile目录用于存储临时文件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;//创建一个名为WordApp的组件对象Word.Application WordApp=new Word.Application();//创建一个名为WordDoc的文档对象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 = "";
//导出到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);//关闭WordApp组件对象WordApp.Quit(ref Nothing, ref Nothing, ref Nothing);return pdfFilename;}

Pdf 转批量 Jpeg

生成pdf文件后,我们需要将其转化到指定目录下,批量生成JPEG图片,以备客户端JS进行调用。

方法介绍:

public void PdfToImage(string pdfInputPath, string imageOutputPath,string imageName)

//参数1:PDF文件路径,参数2:输出图片的路径,参数3:图片文件名的前缀,比如输入Img,则会输出Img_001.jpg、Img_002.jpg。。。以此类推。
 

示例代码如下:

//参数1:PDF文件路径,参数2:输出图片的路径,参数3:图片文件名的前缀,比如输入Img,则会输出Img_001.jpg、Img_002.jpg以此类推
public void PdfToImage(string pdfInputPath, string imageOutputPath,string imageName){//            PdfRenderFlags.Annotations 改成 PdfRenderFlags.CorrectFromDpi DPI值设置成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 转为电子书

根据 turn.js 的格式要求,我们在服务端 Page_Load 事件里生成一个 ViewState,直接输出到客户端,ViewState["result"] 是我们要输出的变量,我们对指定的 jpgTmpPath 变量目录进行遍历,符合jpeg或jpg扩展名的文件则进行记录。

服务端示例代码如下:

protected void Page_Load(object sender, EventArgs e){ViewState["result"] = "";  //关键的viewsate,用于存储JPEG地址数组格式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("没有预览资源");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>电子期刊预览</title><link rel="stylesheet" type="text/css" href="css/basic.css"/><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> 

客户端脚本:

在客户端我们接收来自 ViewState["result"] 的变量值,实现电子书的效果:

<script type="text/javascript">var loading_img_url = [<%=ViewState["result"]%>];
</script>
<script type="text/javascript" src="js/main.js"></script>
<script>//自定义弹出层(function ($) {//ios confirm boxjQuery.fn.confirm = function (title, option, okCall, cancelCall) {var defaults = {title: null, //what textcancelText: '取消', //the cancel btn textokText: '确定' //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="#"></a>').html(o.cancelText).appendTo(dom_btn);var btn_ok = $('<a href="#"></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) {//上一页$(".previousPage").bind("click", function () {var pageCount = $(".flipbook").turn("pages"); //总页数var currentPage = $(".flipbook").turn("page"); //当前页if (currentPage > 2) {$(".flipbook").turn('page', currentPage - 2);} else if (currentPage == 2) {$(".flipbook").turn('page', currentPage - 1);}});// 下一页$(".nextPage").bind("click", function () {var pageCount = $(".flipbook").turn("pages"); //总页数var currentPage = $(".flipbook").turn("page"); //当前页if (currentPage < pageCount - 1) {$(".flipbook").turn('page', currentPage + 2);} else if (currentPage == pageCount - 1) {$(".flipbook").turn('page', currentPage + 1);}});} else {//上一页$(".previousPage").bind("click", function () {var pageCount = $(".flipbook").turn("pages"); //总页数var currentPage = $(".flipbook").turn("page"); //当前页if (currentPage >= 2) {$(".flipbook").turn('page', currentPage - 1);} else {}});// 下一页$(".nextPage").bind("click", function () {var pageCount = $(".flipbook").turn("pages"); //总页数var currentPage = $(".flipbook").turn("page"); //当前页if (currentPage <= pageCount) {$(".flipbook").turn('page', currentPage + 1);} else {}});}//返回到目录页$(".return").bind("click", function () {$(document).confirm('您确定要返回首页吗?', {}, function () {$(".flipbook").turn('page', 1); //跳转页数}, function () {});});function gotopage(pageindex) {$(".flipbook").turn('page',pageindex);}</script>

实现效果演示

小结

以上提供的代码仅供参考,turn.js 我花了一些时间进行了改造,我们也可以根据自己的需要对样式、控制进行改造。其它的一些细节我们可以进一步调整,如图片生成质量、权限控制等。

另外,还可以实现下载、评价、点赞、收藏等其它功能,这里就不再一一介绍。

以上就是自己的一些分享,时间仓促,不妥之处还请大家批评指正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/234837.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis-Plus如何 关闭SQL日志打印

前段时间公司的同事都过来问我&#xff0c;hua哥公司的项目出问题了&#xff0c;关闭不了打印sql日记&#xff0c;项目用宝塔自己部署的&#xff0c;磁盘满了才发现大量的打印sql日记&#xff0c;他们百度过都按照网上的配置修改过不起作用&#xff0c;而且在调试时候也及为不方…

mysql的asc和desc全称

原文&#xff1a;http://t.csdnimg.cn/BJ2sUhttp://t.csdnimg.cn/BJ2sU

[AutoSar]基础部分 RTE 02 S/R Port 显式/隐式

目录 关键词平台说明一、显式&#xff08;Explicit&#xff09;和隐式&#xff08;Implicit&#xff09;1.1 显式模式1.1.1code 二、隐式模式2.1 code 三、区别 关键词 嵌入式、C语言、autosar、EcuM、Rte 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语…

字符串逆序输出

逆序输出就是本来abc输出的&#xff0c;然后我想让他输出成cba&#xff0c;那么我们还是要用到for循环&#xff0c;只不过原先是从零开始往上加&#xff0c;这回呢&#xff0c;是从上面往下减 我们观察上面这个图片&#xff0c;我们想要输出olleh&#xff0c;那么我们就要从4开…

2023 英特尔On技术创新大会直播 |探索视觉AI的无限可能

2023 英特尔On技术创新大会直播 | 探索视觉AI的无限可能 前言一未来的 AI&#xff1a;释放视觉 AI 真正潜力二AI技术突破、视觉Al挑战及前沿研究创新三全尺度视觉学习全尺度视觉学习示例1.GridConv 实现三维人体姿态估计更高准确率2.KW 预训练及迁移模型性能3.无数据增强稠密对…

Gin之GORM事务(转账操作)

禁用默认事务的操作 为了确保数据一致性,GORM 会在事务里执行写入操作(创建、更新、删除)。如果没有这方面的要求,您可以在初始化时禁用它,这将获得大约 30%+ 性能提升。 // 全局禁用 db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{SkipDef…

基于DSP的IIR数字滤波器(论文+源码)

1.系统设计 在本次基于DSP的IIR数字低通滤波计中&#xff0c;拟以TMS320F28335来作为系统的主控制器&#xff0c;通过ADC0832模数转换芯片来对输入信号进行采集&#xff1b;通过TLC5615来将低通滤波后的信号进行输出&#xff1b;同时结合MATLAB仿真软件&#xff0c;对设计的II…

为什么GRU和LSTM能够缓解梯度消失或梯度爆炸问题?

1、什么是梯度消失&#xff08;gradient vanishing&#xff09;&#xff1f; 参数更新过小&#xff0c;在每次更新时几乎不会移动&#xff0c;导致模型无法学习。 2、什么是梯度爆炸&#xff08;gradient exploding&#xff09;&#xff1f; 参数更新过小大&#xff0c;破坏了…

vue3+vite静态页面部署到gitee pages

vue3vite静态页面部署到gitee pages gitee创建开源仓库修改项目部署到gitee中 随着vue3的成熟&#xff0c;vue2将在2023.12.31停止维护&#xff0c;所以有必要搞一下vue3项目静态页面怎么部署到gitee中了 如果还有想部署vue2静态页面到gitee中的话&#xff0c;访问https://blog…

【小呆的力学笔记】弹塑性力学的初步认知二:应力分析(1)

文章目录 1.1 一点的应力状态1.2 一点主应力状态1.3 应力偏张量、球张量、应力不变量 1.1 一点的应力状态 物体在受到外力或者自身不均匀的温度场等作用时&#xff0c;在其内部会产生内力&#xff0c;物体的内力与方向和截面都有关系。假设有一个受到外力作用的变形体&#xf…

ros2 学习04 工作空间说明及示例

ros2 术语说明&#xff1a; 大家在学习其他的开发语言之前的学习和开发中&#xff0c;应该有接触过某些集成开发环境&#xff0c;比如Visual Studio、Eclipse、Qt Creator等&#xff0c;当我们想要编写程序之前&#xff0c;都会在这些开发环境的工具栏中&#xff0c;点击一个“…

c语言力扣题目:消失的数字(有关时间复杂度O(N²)O(N))以及对异或操作符的更深入的理解(如何用人脑的十进制去考量二进制)

目录 Way One :暴力求解,时间复杂度为 O(N) 代码1 Way Two : 时间复杂度限制到 O(N) 代码及其详解 如题 Way One :暴力求解,时间复杂度为 O(N) 大体思路:比如这里我们需要处理的整型数组是"3,0,1",我们可以用冒泡排序或者 qsort函数将他从大到小进行排序成"…

SpringBlade export-user SQL 注入漏洞复现

0x01 产品简介 SpringBlade 是一个由商业级项目升级优化而来的 SpringCloud 分布式微服务架构、SpringBoot 单体式微服务架构并存的综合型项目。 0x02 漏洞概述 SpringBlade v3.2.0 及之前版本框架后台 export-user 路径存在安全漏洞,攻击者利用该漏洞可通过组件customSqlS…

手把手教你在 windows 上安装 Docker

前言 大家好&#xff0c;我是潇潇雨声&#xff0c;今天为大家带来一篇关于在 Windows 环境下使用 Docker 的教程。对于 Docker&#xff0c;我们可以简单地将其看作一种方便的软件安装方式&#xff0c;而无需深入涉及其复杂的概念。选择使用 Docker 主要是为了省事&#xff0c;比…

动态规划系列 | 一文搞定区间DP

文章目录 特点石子合并题目描述问题分析程序代码复杂度分析 环形石子合并题目描述问题分析程序代码复杂度分析 能量项链题目描述问题分析程序代码复杂度分析 加分二叉树题目描述问题分析程序代码复杂度分析 凸多边形的划分题目描述问题分析程序代码复杂度分析 棋盘分割题目描述…

STM32内部是怎么工作的

STM32是怎么工作的 1 从孩子他妈说起2 早期计算机的组成2.1 五大元件&#xff08;1&#xff09;第一个出场的是电容元件&#xff08;2&#xff09;第二个出场的是二极管&#xff08;3&#xff09;第三个出场的是电阻元件&#xff08;4&#xff09;第四个出场的是电感&#xff0…

现代雷达车载应用——第3章 MIMO雷达技术 3.1节 基于MIMO雷达的虚拟阵列合成

经典著作&#xff0c;值得一读&#xff0c;英文原版下载链接【免费】ModernRadarforAutomotiveApplications资源-CSDN文库。 3 MIMO雷达技术 自20世纪90年代末以来&#xff0c;带有少量天线的汽车雷达已被用于高级驾驶员辅助系统(ADAS)的目的。这些早期的汽车雷达主要提供目标…

Flask学习四:补充

插件 flask-caching 简介 Flask-Caching 是一个 Flask 扩展&#xff0c;旨在为 Flask 应用程序添加缓存功能。缓存是一种提高应用性能的技术&#xff0c;通过将常用数据暂时存储在一个快速访问的位置&#xff08;如内存或磁盘&#xff09;&#xff0c;从而减少对较慢资源&…

HarmonyOS应用开发实战—开箱即用的活动创建页面【ArkTS】【鸿蒙专栏-33】

一.HarmonyOS应用开发实战—开箱即用的个人主页页面【ArkTS】【鸿蒙专栏-32】 1.1 项目背景 HarmonyOS(鸿蒙操作系统)是华为公司推出的一种分布式操作系统。它被设计为一种全场景、全连接的操作系统,旨在实现在各种设备之间的无缝协同和共享,包括智能手机、平板电脑、智能…

Android排队预约系统(Java+SqLite+ZXing)

自己写的排队预约系统&#xff0c;可改写&#xff0c;添加功能&#xff0c;如管理用户&#xff0c;查询排队人数等功能。(由于是选修课课设&#xff0c;所以写的比较粗糙) 使用方法&#xff1a; 1.使用Android studio导入项目。 2.使用gradle加载build.gradle.kts中的依赖。…