1.描述

想必很多人在开发项目的时候都遇到过这种需求,就是将一个html一键转成word,然后发现无论如何都没法将界面中的图片给保存下来,其实这是因为图片存在跨域的问题,目前我的解决办法是自己的图片保存在 七牛云 中,就不会出现这个问题了。如何你存储到其他的地方,比如自己的服务器,可能就需要开放自己的跨域(自行解决),如果你的图片是外部连接,比如csdn,这样是没法保存的,csdn上的图片不支持跨域请求。

2.Js代码

2.1.启动Js

function downloadword() {$("#paperque").wordExport(papername);  //fileName为导出的word文件的命名html2canvas(document.getElementById("paperque"), {onrendered: function (canvas) {//通过html2canvas将html渲染成canvas,然后获取图片数据var imgData = canvas.toDataURL('image/jpeg');//初始化pdf,设置相应格式var doc = new jsPDF("p", "mm", "a4");doc.setFillColor(0, 0, 0);//这里设置的是a4纸张尺寸doc.addImage(imgData, 'JPEG', 0, 0, 210, 297);//输出保存命名为content的pdfdoc.save(papername + '.word');}});
}

2.2.wordexport.js

主要是下面这行代码

relimg.setAttribute("crossOrigin",'Anonymous');
if (typeof jQuery !== "undefined" && typeof saveAs !== "undefined") {(function($) {$.fn.wordExport = function(fileName) {fileName = typeof fileName !== 'undefined' ? fileName : "jQuery-Word-Export";var static = {mhtml: {top: "Mime-Version: 1.0\nContent-Base: " + location.href + "\nContent-Type: Multipart/related; boundary=\"NEXT.ITEM-BOUNDARY\";type=\"text/html\"\n\n--NEXT.ITEM-BOUNDARY\nContent-Type: text/html; charset=\"utf-8\"\nContent-Location: " + location.href + "\n\n<!DOCTYPE html>\n<html>\n_html_</html>",head: "<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n<style>\n_styles_\n</style>\n</head>\n",body: "<body>_body_</body>"}};var options = {maxWidth: 624};// Clone selected element before manipulating itvar markup = $(this).clone();// Remove hidden elements from the outputmarkup.each(function() {var self = $(this);if (self.is(':hidden'))self.remove();});// Embed all images using Data URLsvar images = Array();var img = markup.find('img');for (var i = 0; i < img.length; i++) {// Calculate dimensions of output imagevar w = Math.min(img[i].width, options.maxWidth);var h = img[i].height * (w / img[i].width);// Create canvas for converting image to data URLvar canvas = document.createElement("CANVAS");canvas.width = w;canvas.height = h;// Draw image to canvasvar context = canvas.getContext('2d'),relimg = new Image(),//创建新的图片对象base64 = '' ;//base64relimg.src = img[i].src;relimg.setAttribute("crossOrigin",'Anonymous'); //设置图片的跨域属性relimg.onload = function(){//图片加载完,再draw 和 toDataURLcontext.drawImage(relimg,0, 0, w, h);base64 = canvas.toDataURL("image/png");};// Get data URL encoding of imagevar uri = canvas.toDataURL("image/png");$(img[i]).attr("src", img[i].src);img[i].width = w;img[i].height = h;// Save encoded image to arrayimages[i] = {type: uri.substring(uri.indexOf(":") + 1, uri.indexOf(";")),encoding: uri.substring(uri.indexOf(";") + 1, uri.indexOf(",")),location: $(img[i]).attr("src"),data: uri.substring(uri.indexOf(",") + 1)};}// Prepare bottom of mhtml file with image datavar mhtmlBottom = "\n";for (var i = 0; i < images.length; i++) {mhtmlBottom += "--NEXT.ITEM-BOUNDARY\n";mhtmlBottom += "Content-Location: " + images[i].location + "\n";mhtmlBottom += "Content-Type: " + images[i].type + "\n";mhtmlBottom += "Content-Transfer-Encoding: " + images[i].encoding + "\n\n";mhtmlBottom += images[i].data + "\n\n";}mhtmlBottom += "--NEXT.ITEM-BOUNDARY--";//TODO: load css from included stylesheetvar styles = "";// Aggregate parts of the file togethervar fileContent = static.mhtml.top.replace("_html_", static.mhtml.head.replace("_styles_", styles) + static.mhtml.body.replace("_body_", markup.html())) + mhtmlBottom;// Create a Blob with the file contentsvar blob = new Blob([fileContent], {type: "application/msword;charset=utf-8"});saveAs(blob, fileName + ".doc");};})(jQuery);
} else {if (typeof jQuery === "undefined") {console.error("jQuery Word Export: missing dependency (jQuery)");}if (typeof saveAs === "undefined") {console.error("jQuery Word Export: missing dependency (FileSaver.js)");}
}

2.2.fileSavers.js

/* FileSaver.js* A saveAs() FileSaver implementation.* 1.3.2* 2016-06-16 18:25:19** By Eli Grey, http://eligrey.com* License: MIT*   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md*//*global self */
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true *//*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */var saveAs = saveAs || (function(view) {"use strict";// IE <10 is explicitly unsupportedif (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {return;}vardoc = view.document// only get URL when necessary in case Blob.js hasn't overridden it yet, get_URL = function() {return view.URL || view.webkitURL || view;}, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"), can_use_save_link = "download" in save_link, click = function(node) {var event = new MouseEvent("click");node.dispatchEvent(event);}, is_safari = /constructor/i.test(view.HTMLElement), is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent), throw_outside = function(ex) {(view.setImmediate || view.setTimeout)(function() {throw ex;}, 0);}, force_saveable_type = "application/octet-stream"// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to, arbitrary_revoke_timeout = 1000 * 40 // in ms, revoke = function(file) {var revoker = function() {if (typeof file === "string") { // file is an object URLget_URL().revokeObjectURL(file);} else { // file is a Filefile.remove();}};setTimeout(revoker, arbitrary_revoke_timeout);}, dispatch = function(filesaver, event_types, event) {event_types = [].concat(event_types);var i = event_types.length;while (i--) {var listener = filesaver["on" + event_types[i]];if (typeof listener === "function") {try {listener.call(filesaver, event || filesaver);} catch (ex) {throw_outside(ex);}}}}, auto_bom = function(blob) {// prepend BOM for UTF-8 XML and text/* types (including HTML)// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BFif (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});}return blob;}, FileSaver = function(blob, name, no_auto_bom) {if (!no_auto_bom) {blob = auto_bom(blob);}// First try a.download, then web filesystem, then object URLsvarfilesaver = this, type = blob.type, force = type === force_saveable_type, object_url, dispatch_all = function() {dispatch(filesaver, "writestart progress write writeend".split(" "));}// on any filesys errors revert to saving with object URLs, fs_error = function() {if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {// Safari doesn't allow downloading of blob urlsvar reader = new FileReader();reader.onloadend = function() {var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');var popup = view.open(url, '_blank');if(!popup) view.location.href = url;url=undefined; // release reference before dispatchingfilesaver.readyState = filesaver.DONE;dispatch_all();};reader.readAsDataURL(blob);filesaver.readyState = filesaver.INIT;return;}// don't create more object URLs than neededif (!object_url) {object_url = get_URL().createObjectURL(blob);}if (force) {view.location.href = object_url;} else {var opened = view.open(object_url, "_blank");if (!opened) {// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.htmlview.location.href = object_url;}}filesaver.readyState = filesaver.DONE;dispatch_all();revoke(object_url);};filesaver.readyState = filesaver.INIT;if (can_use_save_link) {object_url = get_URL().createObjectURL(blob);setTimeout(function() {save_link.href = object_url;save_link.download = name;click(save_link);dispatch_all();revoke(object_url);filesaver.readyState = filesaver.DONE;});return;}fs_error();}, FS_proto = FileSaver.prototype, saveAs = function(blob, name, no_auto_bom) {return new FileSaver(blob, name || blob.name || "download", no_auto_bom);};// IE 10+ (native saveAs)if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {return function(blob, name, no_auto_bom) {name = name || blob.name || "download";if (!no_auto_bom) {blob = auto_bom(blob);}return navigator.msSaveOrOpenBlob(blob, name);};}FS_proto.abort = function(){};FS_proto.readyState = FS_proto.INIT = 0;FS_proto.WRITING = 1;FS_proto.DONE = 2;FS_proto.error =FS_proto.onwritestart =FS_proto.onprogress =FS_proto.onwrite =FS_proto.onabort =FS_proto.onerror =FS_proto.onwriteend =null;return saveAs;
}(typeof self !== "undefined" && self|| typeof window !== "undefined" && window|| this.content
));
// `self` is undefined in Firefox for Android content script context
// while `this` is nsIContentFrameMessageManager
// with an attribute `content` that corresponds to the windowif (typeof module !== "undefined" && module.exports) {module.exports.saveAs = saveAs;
} else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {define([], function() {return saveAs;});
}

3.使用

引入上面的js,网页中一个按钮,点击这个按钮调用downloadword函数即可,其中文件导出的文件名字可以自定义。

4.视图问题

上面运行后发现文档打开的页面不是 页面视图 ,而是 web视图 ,其实还需要修改wordexport.js。其中var static = {} 修改成如下内容。

var static = {mhtml: {top: "Mime-Version: 1.0\nContent-Base: " + location.href + "\nContent-Type: Multipart/related; boundary=\"NEXT.ITEM-BOUNDARY\";type=\"text/html\"\n\n--NEXT.ITEM-BOUNDARY\nContent-Type: text/html; charset=\"utf-8\"\nContent-Location: " + location.href + "\n\n<!DOCTYPE html>\n" +"<html xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:w=\"urn:schemas-microsoft-com:office:word\" xmlns:m=\"http://schemas.microsoft.com/office/2004/12/omml\" xmlns=\"http://www.w3.org/TR/REC-html40\">\n_html_</html>",head: "<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n<style>\n_styles_\n</style>\n<!--[if gte mso 9]><xml><w:WordDocument><w:View>Print</w:View><w:TrackMoves>false</w:TrackMoves><w:TrackFormatting/><w:ValidateAgainstSchemas/><w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid><w:IgnoreMixedContent>false</w:IgnoreMixedContent><w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText><w:DoNotPromoteQF/><w:LidThemeOther>EN-US</w:LidThemeOther><w:LidThemeAsian>ZH-CN</w:LidThemeAsian><w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript><w:Compatibility><w:BreakWrappedTables/><w:SnapToGridInCell/><w:WrapTextWithPunct/><w:UseAsianBreakRules/><w:DontGrowAutofit/><w:SplitPgBreakAndParaMark/><w:DontVertAlignCellWithSp/><w:DontBreakConstrainedForcedTables/><w:DontVertAlignInTxbx/><w:Word11KerningPairs/><w:CachedColBalance/><w:UseFELayout/></w:Compatibility><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><m:mathPr><m:mathFont m:val=\"Cambria Math\"/><m:brkBin m:val=\"before\"/><m:brkBinSub m:val=\"--\"/><m:smallFrac m:val=\"off\"/><m:dispDef/><m:lMargin m:val=\"0\"/> <m:rMargin m:val=\"0\"/><m:defJc m:val=\"centerGroup\"/><m:wrapIndent m:val=\"1440\"/><m:intLim m:val=\"subSup\"/><m:naryLim m:val=\"undOvr\"/></m:mathPr></w:WordDocument></xml><![endif]--></head>\n",body: "<body>_body_</body>"}
};

其实就是在html之间加入:

<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml"
xmlns="http://www.w3.org/TR/REC-html40">

在head中加入:

<!--[if gte mso 9]><xml><w:WordDocument><w:View>Print</w:View><w:TrackMoves>false</w:TrackMoves><w:TrackFormatting/><w:ValidateAgainstSchemas/><w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid><w:IgnoreMixedContent>false</w:IgnoreMixedContent><w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText><w:DoNotPromoteQF/><w:LidThemeOther>EN-US</w:LidThemeOther><w:LidThemeAsian>ZH-CN</w:LidThemeAsian><w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript><w:Compatibility><w:BreakWrappedTables/><w:SnapToGridInCell/><w:WrapTextWithPunct/><w:UseAsianBreakRules/><w:DontGrowAutofit/><w:SplitPgBreakAndParaMark/><w:DontVertAlignCellWithSp/><w:DontBreakConstrainedForcedTables/><w:DontVertAlignInTxbx/><w:Word11KerningPairs/><w:CachedColBalance/><w:UseFELayout/></w:Compatibility><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><m:mathPr><m:mathFont m:val="Cambria Math"/><m:brkBin m:val="before"/><m:brkBinSub m:val="--"/><m:smallFrac m:val="off"/><m:dispDef/><m:lMargin m:val="0"/> <m:rMargin m:val="0"/><m:defJc m:val="centerGroup"/><m:wrapIndent m:val="1440"/><m:intLim m:val="subSup"/><m:naryLim m:val="undOvr"/></m:mathPr></w:WordDocument></xml><![endif]-->

个人博客原文地址:
Html-Word解决转存图片时候的跨域问题

Html转Word解决转存图片时候的跨域问题、默认打开视图问题相关推荐

  1. 图片裁剪工具vueCropper跨域解决

    图片裁剪工具vueCropper跨域解决 1.报错原因:本项目的图片放在亚马逊,需求是直接拿到网络图片进行裁剪 2.解决:将图片转化成base64 Vue.prototype.getBase64Img ...

  2. JS使用技巧-如何解决谷歌浏览器下载图片、PDF文档时只打开不下载的问题?

    问题描述: 页面下载跨域的图片.pdf文件,浏览器总是自动打开,并且在下载列表里面不显示. 如何解决谷歌浏览器下载图片.PDF文档时只打开不下载的问题?如何变成直接下载? 解决方法: 使用js获取下载 ...

  3. node解决关于请求必应图片API的跨域问题

    关于请求必应图片API的跨域问题 必应每天都会更新一张背景图片,如果我们想要在自己的网站中每天动态得更新这种图标就需要用到API去请求,必应官方API 请求实例: https://cn.bing.co ...

  4. 魔坊APP项目-17-种植园,商城页面、服务端提供商品api,解决App打包编译以后的跨域限制、客户端获取商品列表并进行展示,集成Alipayplus模块完成支付

    种植园 一.商城页面 orchard.html,代码: <!DOCTYPE html> <html> <head><title>用户中心</tit ...

  5. 图片转base64跨域问题

    vue图片转base64跨域问题,亚马逊存储 1.问题说明:如果资源存在是放在国内(如七牛)在转base64的时候不会发生跨域,但本项目存储空间选择的是亚马逊S3,在转化的时候出现了跨域 2.解决 2 ...

  6. 解决java前后端分离端口跨域问题

    解决java前后端分离端口跨域问题 参考文章: (1)解决java前后端分离端口跨域问题 (2)https://www.cnblogs.com/mollie-x/p/10449686.html 备忘一 ...

  7. 解决Django Rest Framework中的跨域问题

    解决Django Rest Framework中的跨域问题 参考文章: (1)解决Django Rest Framework中的跨域问题 (2)https://www.cnblogs.com/qicu ...

  8. 【强烈推荐】如何解决JQuery类Post方式的跨域问题 - 空山雪林通用模块设计工作室 - ITeye技术网站...

    [强烈推荐]如何解决JQuery类Post方式的跨域问题 - 空山雪林通用模块设计工作室 - ITeye技术网站 [强烈推荐]如何解决JQuery类Post方式的跨域问题 博客分类:核心代码片段 jQ ...

  9. Vue整合nginx:(1)开发环境npm run dev下,通过nginx解决前后端分离造成的跨域问题

    Vue整合nginx:(1)开发环境npm run dev下,通过nginx解决前后端分离造成的跨域问题 参考文章: (1)Vue整合nginx:(1)开发环境npm run dev下,通过nginx ...

  10. h5解决外置浏览器和小程序跨域问题

    api.js里面配置你要跨域的域名 然后配置跨域用到的js文件 /**枚举EPlatform*/ export enum EPlatform {/**App*/AppPlus = 'APP-PLUS' ...

最新文章

  1. Internet History, Technology, and Security----第三周
  2. poj-1159 Palindrome **
  3. proe输入数字时成双出现_罗斯蒙特温度变送器3144P单只和双只输入输出的的含义...
  4. nginx echo 输出 检查配置正确性
  5. 利用SQL计算两个地理坐标(经纬度)之间的地表距离
  6. Linux思维导图之sed、实战习题
  7. go kegg_工具篇丨GO和KEGG富集不到通路?快试试这个超赞的功能分析工具吧
  8. Android源码分析(十一)-----Android源码中如何引用aar文件
  9. excel处置4000行数据卡_Pandas读取并修改excel的示例代码
  10. OpenCV cv.INTER_AREA和cv.INTER_CUBIC 还有cv.INTER_LINEAR
  11. 加多宝首度披露"换头手术"的详细内幕
  12. 30分钟写一个聊天板
  13. 都2021年了不会还有人用门禁卡吧!(手把手教你用手机代替门禁卡)
  14. uniCloud开发公众号:一、接收、解析、组装xml消息
  15. VMware教程(二):CentOS 7 网络配置
  16. mysql原理、索引、优化-【公司内部培训】
  17. Data Abort产生的原因
  18. K3s+Rainbond默认集群添加agent节点
  19. fastapi、flask和tornado对获取请求IP的探索
  20. 如何让一个电机转起来

热门文章

  1. java中用窗口求一元二次方程,《一元二次方程求解窗口——Java第十三周》
  2. Vmlogin防关联超级浏览器Selenium浏览器自动化详细教程
  3. 计算机应用基础作业4第一次,《计算机应用基础》第一次作业题目、答案
  4. Servlet的生命周期
  5. linux 可道云_腾讯云linux+kodexplorer可道云搭建私有云盘
  6. 使用3CDaemon 进行ftp 传输文件 (linux-开发板) 的方法
  7. 如何批量压缩图片体积大小kb?
  8. webpower邮件营销平台可以带来什么?
  9. 可以使用C#语言的在线ACM题库
  10. DC-DC转换器分类-和讯康讲堂