前端导出

2024-06-19 54℃
npm install xlsx
npm install file-saver

import * as XLSX from 'xlsx';
import { saveAs } from "file-saver";

//导出文档  markup目标dom,
export function Outword(markup, fileName) {
	var staticdata = {
		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><meta http-equiv=Content-Type content="text/html; charset=utf-8"><title></title><!--[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]--><style>_styles_</style></head>',
			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 (item) {
	//var self = $(this);
	//if (self.is(':hidden'))
	//	self.remove();
	//});

	// Embed all images using Data URLs
	var images = Array();
	var img = markup.querySelectorAll('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);
		// 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");
		//$(img[i]).attr("src", img[i].src);
		img[i].src = img[i].src;
		img[i].width = w;
		img[i].height = h;
		// 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[i].src,
			data: uri.substring(uri.indexOf(",") + 1)
		};
	}

	// 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 = "<!--@font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-alt:SimSun;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 680460288 22 0 262145 0}@font-face{font-family:\"Cambria Math\";panose-1:2 4 5 3 5 4 6 3 2 4;mso-font-charset:1;mso-generic-font-family:roman;mso-font-format:other;mso-font-pitch:variable;mso-font-signature:0 0 0 0 0 0}@font-face{font-family:\"\@宋体\";panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 680460288 22 0 262145 0}p.MsoNormal,li.MsoNormal,div.MsoNormal{mso-style-unhide:no;mso-style-qformat:yes;mso-style-parent:\"\";margin:0cm;margin-bottom:.0001pt;mso-pagination:widow-orphan;font-size:14.0pt;font-family:宋体;mso-bidi-font-family:宋体}p.MsoHeader,li.MsoHeader,div.MsoHeader{mso-style-noshow:yes;mso-style-priority:99;mso-style-link:\"页眉 Char\";margin:0cm;margin-bottom:.0001pt;text-align:center;mso-pagination:widow-orphan;layout-grid-mode:char;font-size:9.0pt;font-family:宋体;mso-bidi-font-family:宋体}p.MsoFooter,li.MsoFooter,div.MsoFooter{mso-style-noshow:yes;mso-style-priority:99;mso-style-link:\"页脚 Char\";margin:0cm;margin-bottom:.0001pt;mso-pagination:widow-orphan;layout-grid-mode:char;font-size:9.0pt;font-family:宋体;mso-bidi-font-family:宋体}p.MsoAcetate,li.MsoAcetate,div.MsoAcetate{mso-style-noshow:yes;mso-style-priority:99;mso-style-link:\"批注框文本 Char\";margin:0cm;margin-bottom:.0001pt;mso-pagination:widow-orphan;font-size:9.0pt;font-family:宋体;mso-bidi-font-family:宋体}span.Char{mso-style-name:\"页眉 Char\";mso-style-noshow:yes;mso-style-priority:99;mso-style-unhide:no;mso-style-locked:yes;mso-style-link:页眉;font-family:宋体;mso-ascii-font-family:宋体;mso-fareast-font-family:宋体;mso-hansi-font-family:宋体}span.Char0{mso-style-name:\"页脚 Char\";mso-style-noshow:yes;mso-style-priority:99;mso-style-unhide:no;mso-style-locked:yes;mso-style-link:页脚;font-family:宋体;mso-ascii-font-family:宋体;mso-fareast-font-family:宋体;mso-hansi-font-family:宋体}span.Char1{mso-style-name:\"批注框文本 Char\";mso-style-noshow:yes;mso-style-priority:99;mso-style-unhide:no;mso-style-locked:yes;mso-style-link:批注框文本;font-family:宋体;mso-ascii-font-family:宋体;mso-fareast-font-family:宋体;mso-hansi-font-family:宋体}p.msochpdefault,li.msochpdefault,div.msochpdefault{mso-style-name:msochpdefault;mso-style-unhide:no;mso-margin-top-alt:auto;margin-right:0cm;mso-margin-bottom-alt:auto;margin-left:0cm;mso-pagination:widow-orphan;font-size:10.0pt;font-family:宋体;mso-bidi-font-family:宋体}span.msonormal0{mso-style-name:msonormal;mso-style-unhide:no}.MsoChpDefault{mso-style-type:export-only;mso-default-props:yes;font-size:10.0pt;mso-ansi-font-size:10.0pt;mso-bidi-font-size:10.0pt;mso-ascii-font-family:\"Times New Roman\";mso-hansi-font-family:\"Times New Roman\";mso-font-kerning:0pt}@page WordSection1{size:595.3pt 841.9pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;mso-header-margin:42.55pt;mso-footer-margin:49.6pt;mso-paper-source:0}div.WordSection1{page:WordSection1}-->";

	// Aggregate parts of the file together
	var fileContent = staticdata.mhtml.top.replace("_html_", staticdata.mhtml.head.replace("_styles_", styles) + staticdata.mhtml.body.replace("_body_", markup.innerHTML)) + mhtmlBottom;

	// Create a Blob with the file contents
	var blob = new Blob([fileContent], {
		type: "application/msword;charset=utf-8"
	});
	saveAs(blob, fileName + ".doc");
}
//导出表格-前置处理
export function OutExcel(tableheader, tabledata, filename) {
	tableheader = Vcopy(tableheader);
	tabledata = Vcopy(tabledata);
	if (tableheader[0][0] == '选择' && tableheader[1][0] == '选择') {
		tableheader[0].splice(0, 1)
		tableheader[1].splice(0, 1)
	}
	if (tableheader[0][tableheader[0].length - 1] == '操作') {
		tableheader[0].splice(tableheader[0].length - 1, 1)
		tableheader[1].splice(tableheader[1].length - 1, 1)
	}
	let json = [tableheader[0]];
	let json2 = [tableheader[0]];
	tabledata.map(t => {
		let temp = [];
		tableheader[1].map(k => {
			temp.push(t[k]);
		})
		json.push(temp);
		if (t.checked) json2.push(temp);
	})
	export2Excel((json2.length == 1 ? json : json2), [], (filename || 'table') + new Date().getTime());
}
//json对象生成表格导出
export function export2Excel(json, fields, filename = '数据') {
	function s2ab(s) {
		if (typeof ArrayBuffer !== 'undefined') {
			var buf = new ArrayBuffer(s.length)
			var view = new Uint8Array(buf)
			for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
			return buf
		} else {
			var buf = new Array(s.length);
			for (var i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xFF;
			return buf;
		}
	}
	let sheetName = filename.replace(/(?!\.[^.]+$)\.|[^\w.]+/g, ''); //excel的文件名称
	if (sheetName.length > 30) sheetName = '1';
	let wb = XLSX.utils.book_new() //工作簿对象包含一SheetNames数组,以及一个表对象映射表名称到表对象。XLSX.utils.book_new实用函数创建一个新的工作簿对象。
	let ws = XLSX.utils.json_to_sheet(json, {
		header: fields,
		skipHeader: true
	}) //将JS对象数组转换为工作表。
	wb.SheetNames.push(sheetName)
	wb.Sheets[sheetName] = ws;
	let defaultCellStyle = {
		// font: {
		// 	name: "Verdana",
		// 	sz: 13,
		// 	color: "FF00FF88"
		// },
		// fill: {
		// 	fgColor: {
		// 		rgb: "FFFFAA00"
		// 	}
		// }
	}; //设置表格的样式
	let wopts = {
		bookType: 'xlsx',
		bookSST: false,
		type: 'binary',
		cellStyles: true,
		defaultCellStyle: defaultCellStyle,
		showGridLines: false
	} //写入的样式
	let wbout = XLSX.write(wb, wopts)
	let blob = new Blob([s2ab(wbout)], {
		type: 'application/octet-stream'
	})
	saveAs(blob, filename + '.xlsx')
}
//导入表格生成json对象
export function Excel2JSON(file, fn) {
	let reader = new FileReader();
	let use_utf8 = true;
	reader.onload = function (e) {
		let data = new Uint8Array(e.target.result);
		let wb = XLSX.read(data, {
			type: 'array',
			codepage: use_utf8 ? 65001 : void 0
		});
		let res = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]) || [];
		fn ? fn(res) : '';
	};
	reader.onerror = function (e) {
		fn ? fn([]) : '';
	}
	reader.readAsArrayBuffer(file);
}
//JSON对象导出JSON文件
export function saveJSON(data, filename) {
	if (!filename) filename = "json.json";
	if (typeof data === "object") {
		data = JSON.stringify(data, undefined, 4);
	}
	// 要创建一个 blob 数据
	let blob = new Blob([data], {
		type: "text/json"
	});
	let a = document.createElement("a");
	a.download = filename;
	// 将blob转换为地址
	// 创建 URL 的 Blob 对象
	a.href = window.URL.createObjectURL(blob);
	// 标签 data- 嵌入自定义属性  屏蔽后也可正常下载
	a.dataset.downloadurl = ["text/json", a.download, a.href].join(":");
	// 添加鼠标事件
	let event = new MouseEvent("click", {});
	// 向一个指定的事件目标派发一个事件
	a.dispatchEvent(event);
}
//文件下载
export function Filedownload(url, name) {
	if (!name) {
		name = url.split('/');
		name = name[name.length - 1];
	}
	let xhr = new XMLHttpRequest()
	xhr.open('GET', url)
	xhr.responseType = 'blob';
	xhr.onload = function () {
		saveAs(xhr.response, name, {})
	}
	xhr.onerror = function () {
		ElMessage.error('无法下载文件');
	}
	xhr.send();
}
标签: 前端技术

非特殊说明,本博所有文章均为博主原创。

上一篇 vscode 优化配置
下一篇 Web安全