当前位置: 首页 > news >正文

jQuery-Word-Export 使用记录及完整修正文件下载 jquery.wordexport.js

参考资料: jQuery-Word-Export导出word_jquery.wordexport.js下载-CSDN博客

近期又需要自己做个 Html2Doc 的解决方案,因为客户又不想要 Html2pdf 的下载了,当初还给我费尽心思解决Html转pdf时中文输出的问题(html转pdf文件下载之最合理的方法支持中文_jspdf.umd.min.js-CSDN博客)以及手机端下载pdf的问题(手机端 Android WebView 获取 blob 链接文件名并下载网页动态生成的 pdf 文件且调用外部程序打开_blob链接怎么打开-CSDN博客)

查了下,基于 IIS 的解决方案,感觉还是参考资料中的相对靠谱,测试了一下,页面上的例子正确工作,输出文件正确,之后逐步添加不同元素测试也正常,但是到加了 img 时就报错了:

问 AI 说是叫检查 jquery.word.export.js 的第 33行:

$('<canvas>').attr("id", "test_word_img_" + i).width(w).height(h).insertAfter(img_id);

看了前后代码,发现是 img 元素没有 id 造成的,这样的话,就需要修复 jquery.word.export.js,以下是修复后的代码,不管 img 有没有 id 都能正确输出了,当然,是交给通义千问去修复的:

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 it  var markup = $(this).clone();// Remove hidden elements from the output  markup.each(function () {var self = $(this);if (self.is(':hidden'))self.remove();});// Embed all images using Data URLs  var images = Array();var img = markup.find('img');for (var i = 0; i < img.length; i++) {// Calculate dimensions of output image  var w = Math.min(img[i].width, options.maxWidth);var h = img[i].height * (w / img[i].width);// Ensure each image has a unique idvar img_id = img[i].id || "dynamic_img_" + i;if (!img[i].id) {$(img[i]).attr("id", img_id);}$('<canvas>').attr("id", "test_word_img_" + i).width(w).height(h).insertAfter("#" + img_id);// Create canvas for converting image to data URL  var canvas = document.createElement("CANVAS");canvas.width = w;canvas.height = h;// Draw image to canvas  var context = canvas.getContext('2d');context.drawImage(img[i], 0, 0, w, h);// Get data URL encoding of image  var uri = canvas.toDataURL("image/png");// Save encoded image to array  images[i] = {type: uri.substring(uri.indexOf(":") + 1, uri.indexOf(";")),encoding: uri.substring(uri.indexOf(";") + 1, uri.indexOf(",")),location: "#" + img_id,data: uri.substring(uri.indexOf(",") + 1)};// Replace original image with canvas in markup$("#" + img_id).replaceWith(canvas);}// Prepare bottom of mhtml file with image data  var 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 stylesheet  var styles = "";// Aggregate parts of the file together  var 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 contents  var 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)");}
}

中间还遇到 img 标签中 src 使用其他网站的链接也会报错:

但是这是由于跨域问题,因此将图片放置到网站本地即可:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Export to DOCX</title><script src="./js/jquery-3.3.1.min.js"></script><script src="./js/FileSaver.js"></script><script src="./js/jquery.wordexport.js"></script>
</head>
<body>
<div id="contentAA"><h1>这是一个标题</h1><h1> Your content here...</h1><p>这是段落内容。</p><img src="./img/01.png" alt="示例图片">	<table border="1"><tr><th>表头1</th><th>表头2</th></tr><tr><td>数据1</td><td>数据2</td></tr></table><img src="./img/02.png" alt="示例图片">	
</div>
<hr/>
<button id="export">导出</button><script>$("#export").click(function(){$("#contentAA").wordExport();});</script>
</body>
</html>

图片也正常导出了,打开导出的文件看了一下,发现是个加了壳的 Html 文件,仔细看了下格式,发现这是 Mhtml 格式的,也即 .MHT 单个网页文件格式:

Mime-Version: 1.0
Content-Base: http://127.0.0.1/html2doc02.html
Content-Type: Multipart/related; boundary="NEXT.ITEM-BOUNDARY";type="text/html"--NEXT.ITEM-BOUNDARY
Content-Type: text/html; charset="utf-8"
Content-Location: http://127.0.0.1/html2doc02.html<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style></style>
</head>
<body><h1>这是一个标题</h1><h1> Your content here...</h1><p>这是段落内容。</p><img src="./img/01.png" alt="示例图片" id="dynamic_img_0">	<table border="1"><tbody><tr><th>表头1</th><th>表头2</th></tr><tr><td>数据1</td><td>数据2</td></tr></tbody></table><img src="./img/02.png" alt="示例图片" id="dynamic_img_1">	
</body></html>
--NEXT.ITEM-BOUNDARY
Content-Location: #dynamic_img_0
Content-Type: image/png
Content-Transfer-Encoding: base64iVBORw0KGgoAAAANSUhEUgAAAFAAAAAwCAYAAACG5f33AAAAAXNSR0IArs4c6QAABRFJREFUaEPtm71rFEEUwN8Zc8ldbAykUjuttJBYSCzEgKLiByiksEghiqKi4EchEQwRjFFiAkoExUKwEKIRESwEC/FvUBS0EKKFJCTx43I5v1beyCxz72Z33ps99i5w297szHu/fd+TZIIgCKDxeBPINAB6s1MvNgAm49cAmJBfA2DNAP5+8xZ+PnoMP5+/gL+TnxLJsWTVSsidPgktPfsT7VOLlyti4K+Xr6A4eA3+fJmCYGYmNZkyLS2w/MPr1M6LOwgZLNy6A9me/c6PWgFwrnMT/J2eBqhBddM++b4uACoGU1PA+agVAGdWrQEsDDMOVZZ0dEB2x1Zo3rMLmrs2eiuO5+mnXgBKZLICTFMhibBRX6n08DEUR2+qn5tWrlAftbX3QCofddEDLI7cCOGZxDAp5c6c8oIo+ag1Bzi7eh0EpZJSNHf+HOROHGUpjYG+0NcfWwH4ZvdUAWpFFACPUmR+4DIs3L33vy0SZGId6DXt5i2bYdnYKPw4cRpQJv1I9tTvpArQVMRHWLQ+tEJu3LVZXsve3ZAfGVIfAPeb7+uH0vhEuKfEsvGl1ADS+IOBOz94ieWC5iKuwAgPLSz49i18HeG1jY1WnEktO3/lkrOmS9UCKbwoRTg0uQCp25qWR89BS5xbuyGMr2idXIhceVTYoeMs18s2F1Lx5+4t5UI+j+tM3BPP/d57KNyeY+3FsdtQHBoWx0OOPGGMlQAsc6FMhtWtcDIhR2Bqfdyim0JsG7nqdGWOPGKAPvC4mdAl8ML9BzDfd1FkfaYnmKUSJ9G55DH3Zrvw3KbusObitHrUleMsxiWwaX0+sZZaoct6XfJ4ATSFYMUf0iEkAWgqhBMbn1grgSJZy7ZAalF65GPrOyUZOkwOGFMBoO36UEWMkigUlcQke0jWegM0XdrsOyk8V4ZW+3z6HCYktK5c/4VwGECzr8v9OABdiaRqAOMOMgtVVQ+1tysIwexsqIMLHi7E0DA/NFwxPtPdg2/2pSAliSQRQHpQVPGJheqPw8fL+k5TaA48c31UzWYqw4m9URYoSSSJABbOni/rI+PS/sKDcSgODEJQKJTJncnnoRUnKwd7RXW1rS+WKOM6jLsXd521E6Eug4to3NEDTNdlEhbRrceOiIabVHiJMnUB0BQYBcK6K9uzT12yLO1cD6Wnz6wzuOzunaq8KE08idTD1ZXQghk/3KIHiHXX165udclie2hDbxsnlRWeMTM/W8FsAnRlz7qwwLIk0tQEyz++K7MCLWTcJATXxIGMKkVsBbMke9YFQFu2MpVAIc1syL1D1fvGZVKbu0qyZxxAST0pCRvWPy6iG+iaL7t9mxpemq2U5A7V10IkCkWdIaknJeexAEYJZQv6Lkhxv0cJLlGI04m46knJed4A6XjdnJJw3ZoqGyW4782dub8EimStN0DqEnpKYoLlzN44Svre3HH2tllsKgBNq9AuYbv0kTT/UYLTDsWnnJFAkaz1tkCaVW3wXLGG68K4Lkk5I43VqQCkypvjLVrqcBNLnOA+dxv6XOlEuyYApRNrn9hDrdCcG0Z9JFr/cSbaNQHItTKfMka/Q63Q50xOTF6UALmdQhKI3JhsWroLuDOJ4ATFNbZyWQJnrCXpFFwDC5s8XHj4Lqft1GdYAdLe1wWo2r9LlK322dL9rACTuIlUANt6l9tU44xq7RH5n0rVyKoopNTdFpP1oX6Nf/VKaIoNgA2ACQkkfP0f773NrWxc5+8AAAAASUVORK5CYII=--NEXT.ITEM-BOUNDARY
Content-Location: #dynamic_img_1
Content-Type: image/png
Content-Transfer-Encoding: base64iVBORw0KGgoAAAANSUhEUgAAABMAAAALCAYAAACd1bY6AAAAAXNSR0IArs4c6QAAAHRJREFUOE9j/P///38GKgFGUgxT3uSLYu1dv80ofBTD0BXDVMI0geSxsWHqMAxDtw2XAcjiGIbBXIXPMGQ/ETQM3SCQZmyacFkM9yYxLkMOU2wWY40AZIUwl+GyDNnrGEkDW4yCDMcV08gxTlI6I5S2qWoYAMYcbeBk+Zz2AAAAAElFTkSuQmCC--NEXT.ITEM-BOUNDARY--

既然如此,那么就有很多方法可以输出这种格式的文件了。不一定非得用 jQuery-Word-Export 了,而且从代码看 jquery.wordexport.js ,还可以做很多优化和自定义,现在这个只能勉强算是验证,还不能投入实用。

刚刚测试了 <img src="data:image/png;base64,  格式的图片,发现无法输出后无法在 word 2003 中显示,是因为没有处理 Src 和图片资源区 Content-Location: #dynamic_img_0 这样的设置不对造成的,按照 MHTML 格式规范,手工修改了一下下载的文件,在 Word 2003 里面就能正确显示图片了:

Mime-Version: 1.0
Content-Type: Multipart/related; boundary="NEXT.ITEM-BOUNDARY";type="text/html"--NEXT.ITEM-BOUNDARY
Content-Type: text/html; charset="utf-8"<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style></style>
</head>
<body><h1>这是一个标题</h1><p>这是段落内容。</p><img src="02.png" alt="示例图片">	<table border="1"><tbody><tr><th>表头1</th><th>表头2</th></tr><tr><td>数据1</td><td>数据2</td></tr></tbody></table><img src="01.png" alt="示例图片">	
</body></html>
--NEXT.ITEM-BOUNDARY
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-Location: 01.pngiVBORw0KGgoAAAANSUhEUgAAAFAAAAAwCAYAAACG5f33AAAAAXNSR0IArs4c6QAABRFJREFUaEPtm71rFEEUwN8Zc8ldbAykUjuttJBYSCzEgKLiByiksEghiqKi4EchEQwRjFFiAkoExUKwEKIRESwEC/FvUBS0EKKFJCTx43I5v1beyCxz72Z33ps99i5w297szHu/fd+TZIIgCKDxeBPINAB6s1MvNgAm49cAmJBfA2DNAP5+8xZ+PnoMP5+/gL+TnxLJsWTVSsidPgktPfsT7VOLlyti4K+Xr6A4eA3+fJmCYGYmNZkyLS2w/MPr1M6LOwgZLNy6A9me/c6PWgFwrnMT/J2eBqhBddM++b4uACoGU1PA+agVAGdWrQEsDDMOVZZ0dEB2x1Zo3rMLmrs2eiuO5+mnXgBKZLICTFMhibBRX6n08DEUR2+qn5tWrlAftbX3QCofddEDLI7cCOGZxDAp5c6c8oIo+ag1Bzi7eh0EpZJSNHf+HOROHGUpjYG+0NcfWwH4ZvdUAWpFFACPUmR+4DIs3L33vy0SZGId6DXt5i2bYdnYKPw4cRpQJv1I9tTvpArQVMRHWLQ+tEJu3LVZXsve3ZAfGVIfAPeb7+uH0vhEuKfEsvGl1ADS+IOBOz94ieWC5iKuwAgPLSz49i18HeG1jY1WnEktO3/lkrOmS9UCKbwoRTg0uQCp25qWR89BS5xbuyGMr2idXIhceVTYoeMs18s2F1Lx5+4t5UI+j+tM3BPP/d57KNyeY+3FsdtQHBoWx0OOPGGMlQAsc6FMhtWtcDIhR2Bqfdyim0JsG7nqdGWOPGKAPvC4mdAl8ML9BzDfd1FkfaYnmKUSJ9G55DH3Zrvw3KbusObitHrUleMsxiWwaX0+sZZaoct6XfJ4ATSFYMUf0iEkAWgqhBMbn1grgSJZy7ZAalF65GPrOyUZOkwOGFMBoO36UEWMkigUlcQke0jWegM0XdrsOyk8V4ZW+3z6HCYktK5c/4VwGECzr8v9OABdiaRqAOMOMgtVVQ+1tysIwexsqIMLHi7E0DA/NFwxPtPdg2/2pSAliSQRQHpQVPGJheqPw8fL+k5TaA48c31UzWYqw4m9URYoSSSJABbOni/rI+PS/sKDcSgODEJQKJTJncnnoRUnKwd7RXW1rS+WKOM6jLsXd521E6Eug4to3NEDTNdlEhbRrceOiIabVHiJMnUB0BQYBcK6K9uzT12yLO1cD6Wnz6wzuOzunaq8KE08idTD1ZXQghk/3KIHiHXX165udclie2hDbxsnlRWeMTM/W8FsAnRlz7qwwLIk0tQEyz++K7MCLWTcJATXxIGMKkVsBbMke9YFQFu2MpVAIc1syL1D1fvGZVKbu0qyZxxAST0pCRvWPy6iG+iaL7t9mxpemq2U5A7V10IkCkWdIaknJeexAEYJZQv6Lkhxv0cJLlGI04m46knJed4A6XjdnJJw3ZoqGyW4782dub8EimStN0DqEnpKYoLlzN44Svre3HH2tllsKgBNq9AuYbv0kTT/UYLTDsWnnJFAkaz1tkCaVW3wXLGG68K4Lkk5I43VqQCkypvjLVrqcBNLnOA+dxv6XOlEuyYApRNrn9hDrdCcG0Z9JFr/cSbaNQHItTKfMka/Q63Q50xOTF6UALmdQhKI3JhsWroLuDOJ4ATFNbZyWQJnrCXpFFwDC5s8XHj4Lqft1GdYAdLe1wWo2r9LlK322dL9rACTuIlUANt6l9tU44xq7RH5n0rVyKoopNTdFpP1oX6Nf/VKaIoNgA2ACQkkfP0f773NrWxc5+8AAAAASUVORK5CYII=--NEXT.ITEM-BOUNDARY
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-Location: 02.pngiVBORw0KGgoAAAANSUhEUgAAABMAAAALCAYAAACd1bY6AAAAAXNSR0IArs4c6QAAAHRJREFUOE9j/P///38GKgFGUgxT3uSLYu1dv80ofBTD0BXDVMI0geSxsWHqMAxDtw2XAcjiGIbBXIXPMGQ/ETQM3SCQZmyacFkM9yYxLkMOU2wWY40AZIUwl+GyDNnrGEkDW4yCDMcV08gxTlI6I5S2qWoYAMYcbeBk+Zz2AAAAAElFTkSuQmCC--NEXT.ITEM-BOUNDARY--

下一步就是继续修正 jquery.word.export.js 让它能正确按照这个格式输出文件,并且正确处理 <img  的 Src 属性。 

下面补充一下 FileSaver.js ,省得还要去 github下载,好麻烦:

/* 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 unsupported  if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {  return;  }  var  doc = 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 URL  get_URL().revokeObjectURL(file);  } else { // file is a File  file.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 BF  if (/^\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 URLs  var  filesaver = 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 urls  var 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 dispatching  filesaver.readyState = filesaver.DONE;  dispatch_all();  };  reader.readAsDataURL(blob);  filesaver.readyState = filesaver.INIT;  return;  }  // don't create more object URLs than needed  if (!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.html  view.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 window  if (typeof module !== "undefined" && module.exports) {  module.exports.saveAs = saveAs;  
} else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {  define([], function() {  return saveAs;  });  
}  

相关文章:

jQuery-Word-Export 使用记录及完整修正文件下载 jquery.wordexport.js

参考资料&#xff1a; jQuery-Word-Export导出word_jquery.wordexport.js下载-CSDN博客 近期又需要自己做个 Html2Doc 的解决方案&#xff0c;因为客户又不想要 Html2pdf 的下载了&#xff0c;当初还给我费尽心思解决Html转pdf时中文输出的问题&#xff08;html转pdf文件下载之…...

云服务器部署WebSocket项目

WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;其设计的目的是在Web浏览器和Web服务器之间进行实时通信&#xff08;实时Web&#xff09; WebSocket协议的优点包括&#xff1a; 1. 更高效的网络利用率&#xff1a;与HTTP相比&#xff0c;WebSocket的握手只…...

C#+数据库 实现动态权限设置

将权限信息存储在数据库中&#xff0c;支持动态调整。根据用户所属的角色、特定的功能模块&#xff0c;动态加载权限” 1. 数据库设计 根据这种需求&#xff0c;可以通过以下表设计&#xff1a; 用户表 (Users)&#xff1a;存储用户信息。角色表 (Roles)&#xff1a;存储角色…...

(原创)Android Studio新老界面UI切换及老版本下载地址

前言 这两天下载了一个新版的Android Studio&#xff0c;发现整个界面都发生了很大改动&#xff1a; 新的界面的一些设置可参考一些博客&#xff1a; Android Studio新版UI常用设置 但是对于一些急着开发的小伙伴来说&#xff0c;没有时间去适应&#xff0c;那么怎么办呢&am…...

Ubuntu24虚拟机-gnome-boxes

推荐使用gnome-boxes&#xff0c; virtualbox构建失败&#xff0c;multipass需要开启防火墙 sudo apt install gnome-boxes创建完毕&#xff5e;...

k8s rainbond centos7/win10 -20241124

参考 https://www.rainbond.com/ 国内一站式云原生平台 对centos7环境支持不太行 [lighthouseVM-16-5-centos ~]$ curl -o install.sh https://get.rainbond.com && bash ./install.sh 2024-11-24 09:56:57 ERROR: Ops! Docker daemon is not running. Start docke…...

SpringBoot+Vue滑雪社区网站设计与实现

【1】系统介绍 研究背景 随着互联网技术的快速发展和冰雪运动的普及&#xff0c;滑雪作为一种受欢迎的冬季运动项目&#xff0c;吸引了越来越多的爱好者。与此同时&#xff0c;社交媒体和在线社区平台的兴起为滑雪爱好者提供了一个交流经验、分享心得、获取信息的重要渠道。滑…...

MySql.2

sql查询语句执行过程 SQL 查询语句的执行过程是一个复杂的过程&#xff0c;涉及多个步骤。以下是典型的关系数据库管理系统 (RDBMS) 中 SQL 查询语句的执行过程概述&#xff1a; 1. ‌客户端发送查询‌ 用户通过 SQL 客户端或应用程序发送 SQL 查询语句给数据库服务器。 2. ‌…...

算法之区间和题目讲解

题干 难度&#xff1a;简单 题目分析 题目要求算出每个指定区间内元素的总和。 然而&#xff0c;区间在输入的最下面&#xff0c;所以按照暴力破解的思路&#xff0c;我们首先要遍历数组&#xff0c;把它的值都存进去。 然后&#xff0c;遍历下面的区间&#xff0c;从索引a…...

价格分类(神经网络)

# 1.导入依赖包 import timeimport torch import torch.nn as nn import torch.optim as optimfrom torch.utils.data import TensorDataset, DataLoader from sklearn.model_selection import train_test_splitimport numpy as np import pandas as pd import matplotlib.pypl…...

对智能电视直播App的恶意监控

首先我们要指出中国广电总局推出的一个政策性文件是恶意监控的始作俑者&#xff0c;这个广电总局的政策性文件禁止智能电视和电视盒子安装直播软件。应该说这个政策性文件是为了保护特殊利益集团&#xff0c;阻挠技术进步和发展的。 有那么一些电视机和电视盒子的厂商和电信运…...

【JavaEE初阶】多线程初阶下部

文章目录 前言一、volatile关键字volatile 能保证内存可见性 二、wait 和 notify2.1 wait()方法2.2 notify()方法2.3 notifyAll()方法2.4 wait 和 sleep 的对比&#xff08;面试题&#xff09; 三、多线程案例单例模式 四、总结-保证线程安全的思路五、对比线程和进程总结 前言…...

macOS上进行Ant Design Pro实战教程(一)

由于一个AI项目的前端使用了umi&#xff0c;本教程根据阿里官网上的 《Ant Design 实战教程&#xff08;beta 版&#xff09;》来实操一下&#xff0c;我使用macOS操作系统&#xff0c;VS Code 开发环境。 一、开发环境 1、安装nodejs, npm, yarn 官网上建议使用cnpm&#xf…...

智能合约运行原理

点个关注吧&#xff01;&#xff01; 用一句话来总结&#xff0c;智能合约就像是一个自动售货机&#xff1a;你投入硬币&#xff08;触发条件&#xff09;&#xff0c;选择商品&#xff08;执行合约&#xff09;&#xff0c;然后机器就会自动给你商品&#xff08;执行结果&…...

安卓动态添加View

在安卓应用中&#xff0c;有很多时候需要动态添加View。比如从后台获取商品列表&#xff0c;根据商品数量在页面渲染对应数量的条目&#xff0c;这时候就需要动态添加View。 1.动态添加View的方法 动态添加View有两种方法&#xff1a; 由代码生成子View&#xff1a;这种方式…...

前端预览pdf文件流

需求 后端接口返回pdf文件流&#xff0c;实现新窗口预览pdf。 解决方案 把后端返回的pdf文件流转为blob路径&#xff0c;利用浏览器直接预览。 具体实现步骤 1、引入axios import axios from axios;2、创建预览方法&#xff08;具体使用时将axios的请求路径替换为你的后端…...

【测试工具JMeter篇】JMeter性能测试入门级教程(一)出炉,测试君请各位收藏了!!!

一、前言 Apache JMeter是纯Java的开源软件&#xff0c;最初由Apache软件基金会的Stefano Mazzocchi开发&#xff0c;旨在加载测试功能行为和测量性能。可以使用JMeter进行性能测试&#xff0c;即针对重负载、多用户和并发流量测试Web应用程序。 我们选择JMeter原因 是否测试过…...

【zookeeper03】消息队列与微服务之zookeeper集群部署

ZooKeeper 集群部署 1.ZooKeeper 集群介绍 ZooKeeper集群用于解决单点和单机性能及数据高可用等问题。 集群结构 Zookeeper集群基于Master/Slave的模型 处于主要地位负责处理写操作)的主机称为Leader节点&#xff0c;处于次要地位主要负责处理读操作的主机称为 follower 节点…...

从 Llama 1 到 3.1:Llama 模型架构演进详解

编者按&#xff1a; 面对 Llama 模型家族的持续更新&#xff0c;您是否想要了解它们之间的关键区别和实际性能表现&#xff1f;本文将探讨 Llama 系列模型的架构演变&#xff0c;梳理了 Llama 模型从 1.0 到 3.1 的完整演进历程&#xff0c;深入剖析了每个版本的技术创新&#…...

UE5肉鸽游戏教程学习

学习地址推荐&#xff1a;UE5肉鸽项目实战教程_哔哩哔哩_bilibili...

Vue3 - 详细实现虚拟列表前端虚拟滚动列表解决方案,vue3长列表优化之虚拟列表,解决列表动态高度不固定高度及图片视频图文异步请求加载问题,虚拟列表DOM大量数据同时加载渲染卡顿太慢及下滑列表闪烁

前言 Vue2 版本,请访问 这篇文章 在 vue3 项目开发中,详解实现虚拟列表高度不固定(不定高)且复杂含有图片视频等复杂虚拟列表教程,决列表每项高度不确定及img图像或视频的加载方案,利用缓冲区技术解决用户浏览时渲染不及时列表闪烁白屏/列表加载闪屏,解vue3实现虚拟列表优…...

英语知识网站开发:Spring Boot框架技巧

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了英语知识应用网站的开发全过程。通过分析英语知识应用网站管理的不足&#xff0c;创建了一个计算机管理英语知识应用网站的方案。文章介绍了英语知识应用网站的系…...

基于lvgl+ST7735制作一款esp8285的控制面板程序

要在ESP8285上使用LVGL和ST7735创建一个控制面板程序,你需要遵循以下步骤。这个过程包括设置开发环境,连接硬件,编写代码,以及调校和优化。 所需硬件 ESP8285 开发板:像NodeMCU之类的开发板。ST7735 显示屏:通常是1.8英寸或2.0英寸的SPI接口显示屏。电源和连接线:用于连…...

MySQL 索引详解

在数据库的世界中&#xff0c;索引就像是一本巨大书籍的目录&#xff0c;它能够极大地提高数据检索的效率。在 MySQL 中&#xff0c;索引的合理使用对于数据库的性能至关重要。本文将深入探讨 MySQL 索引的各个方面。 一、索引的概念与作用 1. 什么是索引&#xff1f; 索引是一…...

区块链学习笔记(1)--区块、链和共识 区块链技术入门

常见的hash算法&#xff1a; 文件防篡改&#xff1a;MD5比特币挖矿&#xff1a;SHA256证明数据片段&#xff1a;Merkle root文本去重&#xff1a;SimHash 区块 区块&#xff08;block&#xff09;由区块头&#xff08;block header&#xff09;和交易列表&#xff08;transac…...

【Android+多线程】IntentService 知识总结:应用场景 / 使用步骤 / 源码分析

定义 IntentService 是 Android中的一个封装类&#xff0c;继承自四大组件之一的Service 功能 处理异步请求 & 实现多线程 应用场景 线程任务 需 按顺序、在后台执行 最常见的场景&#xff1a;离线下载不符合多个数据同时请求的场景&#xff1a;所有的任务都在同一个T…...

Python Tornado框架教程:高性能Web框架的全面解析

Python Tornado框架教程&#xff1a;高性能Web框架的全面解析 引言 在现代Web开发中&#xff0c;选择合适的框架至关重要。Python的Tornado框架因其高性能和非阻塞I/O特性而备受青睐。它特别适合处理大量并发连接的应用&#xff0c;比如聊天应用、实时数据处理和WebSocket服务…...

通过端口测试验证网络安全策略

基于网络安全需求&#xff0c;项目中的主机间可能会有不同的网络安全策略&#xff0c;这当然是好的&#xff0c;但很多时候&#xff0c;在解决网络安全问题的时候&#xff0c;同时引入了新的问题&#xff0c;如k8s集群必须在主机间开放udp端口&#xff0c;否则集群不能正常的运…...

Excel把其中一张工作表导出成一个新的文件

excel导出一张工作表 一个Excel表里有多个工作表&#xff0c;怎么才能导出一个工作表&#xff0c;让其生成新的Excel文件呢&#xff1f; 第一步&#xff1a;首先打开Excel表格&#xff0c;然后选择要导出的工作表的名字&#xff0c;比如“Sheet1”&#xff0c;把鼠标放到“She…...

第四份工作的环境配置

最近在内网中工作,会遇到不少的环境问题. 下面记录一下这个过程中的挑战: 环境:内网,连接不到外网. 如何配置开发环境: 方法0: 在服务器上安装环境. 但是服务器上没有相应的python包.因为python包是从外界获得的.并且,这些python包不能同步更新.所以,在服务器上直接搭建环…...

论文中引用网站怎么写/seo优化的方法有哪些

Seata 是什么 Seata 是阿里近期开源的分布式事务框架&#xff0c;地址&#xff1a;github.com/seata/seata。框架包括了集团的 TXC&#xff08;云版本叫 GTS&#xff09;和蚂蚁金服的 TCC 两种模式&#xff0c;短短数月 Github 上的 star 数已经接近一万&#xff0c;算是目前唯…...

兰州 网站建设/手机搜索引擎排行榜

1、遇到的bug 我通过APP客户端上传图片时&#xff0c;却发现服务器根本没有接受到此图片&#xff0c;后来才发现图片是3.9M&#xff0c;超过tomcat对http的post请求的默认接收大小2M的限制。 2、问题的根源 tomcat默认设置能接收HTTP POST请求的大小最大为2M,如果你的POST请求传…...

网站后台验证码无法显示/seo优化培训机构

阅读本文前&#xff0c;请您先点击上面蓝色字体“恋情屋”再点击“关注”&#xff0c;这样您就可以免费收到我们的最新内容了&#xff0c;每天都会有更新&#xff0c;完全是免费订阅&#xff0c;请放心关注。 注&#xff1a;本文转载自网络&…...

网站制作眼/网页模板怎么用

华为的HCIP的考试是三门课程 考试代码腾科认证考试H12-221HCIP-Routing & Switching-IERS&#xff08;Implementing Enterprise Routing and Switching Network&#xff09;H12-222HCIP-Routing & Switching-IENP&#xff08;Improving Enterprise Network Performance…...

成都seo经理/seo研究中心道一老师

HTML通过jQuery引入模板 完整报错新创建一个chrome快捷方式&#xff0c;命名为chrome-debug右键属性&#xff0c;在目标后添加参数,原始路径如下"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" 添加参数后如下"C:\Program Files (x86)\Google\…...

越南做网站服务器/天津海外seo

最近在整理测试用例&#xff0c;所以想找一个合适的工具来完成对测试需求、测试用例的管理。对比了一翻&#xff0c;发现开源工具中扩展比较好的还属TestLink&#xff0c;而且还可以与JIRA进行对接&#xff0c;这样就引起了我更大的兴趣。加上之前本来就接触过此工具&#xff0…...