บทความนี้อธิบายวิธีการส่งออก Excel โดย JavaScript แบ่งปันสำหรับการอ้างอิงของคุณ วิธีการใช้งานเฉพาะมีดังนี้:
การคัดลอกรหัสมีดังนี้: <html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv = "content-type" content = "text/html; charset = utf-8"/>
<title> วิธีส่งออกเว็บเพจเป็นเอกสาร Excel </title>
</head>
<body>
<table id = "tableExcel" cellpacing = "0" cellpadding = "0">
<tr>
<td colspan = "5" allign = "center"> วิธีส่งออกเว็บเพจเป็นเอกสาร excel </td>
</tr>
<tr>
<td> ชื่อคอลัมน์ 1 </td>
<td> ชื่อคอลัมน์ 2 </td>
<td> ชื่อคอลัมน์ 3 </td>
<td> ชื่อคอลัมน์ 4 </td>
<td> ชื่อคอลัมน์ 5 </td>
</tr>
<tr>
<td> AAA </td>
<td> BBB </td>
<td> CCC </td>
<td> ddd </td>
<td> ee </td>
</tr>
<tr>
<td> AAA </td>
<td> BBB </td>
<td> CCC </td>
<td> ddd </td>
<td> eee </td>
</tr>
<tr>
<td> fff </td>
<td> ggg </td>
<Td> HHH </td>
<td> III </td>
<td> jjj </td>
</tr>
</table>
<อินพุต type = "ปุ่ม" onclick = "JavaScript: method1 ('tableExcel');" value = "วิธีแรกนำเข้าสู่ Excel">
<อินพุต type = "ปุ่ม" onclick = "JavaScript: method2 ('tableExcel');" value = "วิธีที่สองนำเข้าสู่ Excel">
<อินพุต type = "ปุ่ม" onclick = "JavaScript: getxlsfromtbl ('tableExcel', null);" value = "วิธีที่สามนำเข้าสู่ Excel">
<ภาษาสคริปต์ = "JavaScript">
ฟังก์ชั่นวิธีการ 1 (tableId) {// คัดลอกทั้งตารางเป็น excel
var curcbl = document.getElementByIdx_x_x (tableId);
var oxl = new ActiveXObject ("excel.application");
// สร้าง Axe Object Excel
var owb = oxl.workbooks.add ();
// รับวัตถุเวิร์กบุ๊ก
var osheet = owb.activeSheet;
// เปิดใช้งานแผ่นปัจจุบัน
var sel = document.body.createTextrange ();
Sel.MoVetOelementText (CURTBL);
// ย้ายเนื้อหาในตารางไปยัง textrange
sel.select ();
// เลือกเนื้อหาทั้งหมดใน Textrange
sel.execcommand ("คัดลอก");
// คัดลอกเนื้อหาใน Textrange
osheet.paste ();
// วางลงใน Excel ที่ใช้งานอยู่
oxl.visible = true;
// ตั้งค่าแอตทริบิวต์ Excel ที่มองเห็นได้
-
ฟังก์ชัน Method2 (TableID) // อ่านแต่ละเซลล์ในตารางลงใน Excel
-
var curcbl = document.getElementByIdx_x_x (tableId);
var oxl = new ActiveXObject ("excel.application");
// สร้าง Axe Object Excel
var owb = oxl.workbooks.add ();
// รับวัตถุเวิร์กบุ๊ก
var osheet = owb.activeSheet;
// เปิดใช้งานแผ่นปัจจุบัน
var lenr = curtbl.rows.length;
// รับจำนวนแถวในตาราง
สำหรับ (i = 0; i <lenr; i ++)
-
var lenc = curtbl.rows (i) .cells.length;
// รับจำนวนคอลัมน์ต่อแถว
สำหรับ (j = 0; j <lenc; j ++)
-
osheet.cells (i + 1, j + 1) .value = curtbl.rows (i) .cells (j) .innerText;
//งานที่มอบหมาย
-
-
oxl.visible = true;
// ตั้งค่าแอตทริบิวต์ Excel ที่มองเห็นได้
-
ฟังก์ชั่น getxlsfromtbl (intblid, inwindow) {
พยายาม {
var Allstr = "";
var curstr = "";
// Alert ("getxlsfromtbl");
if (intblid! = null && intblid! = "" && intblid! = "null") {
curstr = gettbldata (intblid, inwindow);
-
if (curstr! = null) {
Allstr += Curstr;
-
อื่น {
การแจ้งเตือน ("ตารางที่คุณต้องการส่งออกไม่มีอยู่!");
กลับ;
-
var filename = getExCelfilename ();
dofileexport (ชื่อไฟล์, Allstr);
-
จับ (e) {
การแจ้งเตือน ("ข้อยกเว้นเกิดขึ้นในการส่งออก:" + e.name + "->" + e.description + "!");
-
-
ฟังก์ชั่น gettbldata (intbl, inwindow) {
var rows = 0;
// Alert ("getTblData คือ" + inwindow);
var tblDocument = เอกสาร;
ถ้า (!! inwindow && inwindow! = "") {
if (! document.all (inwindow)) {
คืนค่า null;
-
อื่น {
tblDocument = eval_r (inwindow) .document;
-
-
var curcbl = tblDocument.getElementByIdx_x_x (intbl);
var outstr = "";
if (currbl! = null) {
สำหรับ (var j = 0; j <curtbl.rows.length; j ++) {
// Alert ("J คือ" + J);
สำหรับ (var i = 0; i <curtbl.rows [j] .cells.length; i ++) {
// Alert ("ฉันคือ" + i);
ถ้า (i == 0 && แถว> 0) {
Outstr += "";
แถว -= 1;
-
outstr + = curtbl.rows [j] .cells [i] .innerText + "";
if (curtbl.rows [j] .cells [i] .colspan> 1) {
สำหรับ (var k = 0; k <curtbl.rows [j] .cells [i] .colspan - 1; k ++) {
Outstr += "";
-
-
ถ้า (i == 0) {
if (rows == 0 && curtbl.rows [j] .cells [i] .rowspan> 1) {
ROWS = CURTBL.ROWS [J] .CELLS [I] .ROWSPAN - 1;
-
-
-
Outstr += "";
-
-
อื่น {
outstr = null;
การแจ้งเตือน (intbl + "ไม่มีอยู่!");
-
กลับไปข้างนอก;
-
ฟังก์ชั่น getExCelfilename () {
var d = วันที่ใหม่ ();
var curyear = d.getyear ();
var curmonth = "" + (d.getMonth () + 1);
var curdate = "" + d.getdate ();
var curhour = "" + d.getHours ();
var curminute = "" + d.getMinutes ();
var cursecond = "" + d.getSeconds ();
if (curmonth.length == 1) {
curmonth = "0" + curmonth;
-
if (curdate.length == 1) {
Curdate = "0" + Curdate;
-
if (curhour.length == 1) {
curhour = "0" + curhour;
-
if (curminute.length == 1) {
curminute = "0" + curminute;
-
if (cursecond.length == 1) {
cursecond = "0" + cursecond;
-
var filename = "leo_zhang" + "_" + curyear + curmonth + curdate + "_"
+ curhour + curminute + cursecond + ".csv";
// Alert (ชื่อไฟล์);
คืนชื่อไฟล์;
-
ฟังก์ชั่น dofileexport (inname, instr) {
var xlswin = null;
if (!! document.all ("glbhidefrm")) {
xlswin = glbhidefrm;
-
อื่น {
var width = 6;
ความสูง var = 4;
var openpara = "left =" + (window.screen.width / 2 - ความกว้าง / 2)
+ ", top =" + (window.screen.height / 2 - ความสูง / 2)
+ ", scrollbars = no, width =" + width + ", ความสูง =" + ความสูง;
xlswin = window.open ("", "_blank", openpara);
-
xlswin.document.write (Instr);
xlswin.document.close ();
xlswin.document.execcommand ('saveas', true, inname);
xlswin.close ();
-
</script>
</body>
</html>
ต่อไปนี้เป็นปัญหาของการจัดการกับการปิดกระบวนการ Excel
คัดลอกรหัสดังนี้: // ปัญหาการทำลายล้างใน JavaScript (ตัวอย่างวัตถุ ActiveX)
-
<script>
var strsavelocation = 'ไฟล์: /// e: /1.xls'
ฟังก์ชั่น createxls () {
var excel = new ActiveXObject ("excel.application");
var wk = excel.workbooks.add ();
wk.saveas (strsavelocation);
wk.saved = true;
Excel.quit ();
-
ฟังก์ชั่น writexls () {
var excel = new ActiveXObject ("excel.application");
var wk = excel.workbooks.open (strsavelocation);
var sheet = wk.worksheets (1);
sheet.cells (1, 1) .Value = 'สตริงทดสอบ';
wk.saveas (strsavelocation);
wk.saved = true;
Excel.quit ();
-
</script>
<body>
<ปุ่ม onclick = "createxls ()"> สร้าง </button>
<ปุ่ม onclick = "writexls ()"> rewrite </button>
</body>
ในตัวอย่างนี้จะไม่มีข้อยกเว้นเกิดขึ้นเมื่อใช้งานไฟล์ท้องถิ่น -ส่วนใหญ่มีเพียงขยะหน่วยความจำ อย่างไรก็ตามหาก strsavelocation เป็น URL ระยะไกลจะมีการบันทึกข้อมูลรับรองการเข้าถึงไฟล์ในเครื่องและสามารถใช้อินสแตนซ์ (ระยะไกล) เพียงหนึ่งเดียวเท่านั้นเพื่อเปิดใช้งานเอกสาร Excel และจัดเก็บ ดังนั้นหากคุณคลิกปุ่ม "เขียนซ้ำ" ซ้ำ ๆ ข้อยกเว้นจะปรากฏขึ้น
- โปรดทราบว่านี่เป็นรหัสที่เรียบง่ายสำหรับอินสแตนซ์ของไฟล์ที่ใช้ร่วมกันเมื่อทำงานใน SPS ดังนั้นจึงไม่ใช่การอภิปราย "วิชาการ" ที่น่าเบื่อและเป็นปัญหาในทางปฏิบัติในด้านวิศวกรรม
การแก้ปัญหานี้มีความซับซ้อน มันเกี่ยวข้องกับสองประเด็น:
①การเปิดตัวบัตรกำนัลท้องถิ่น
②การเปิดตัวอินสแตนซ์ของวัตถุ ActiveX
เริ่มต้นด้วยปัญหา "ความล้มเหลว" ของวัตถุใน JavaScript พูดง่ายๆ:
①วัตถุจะไม่ถูกต้องนอกบริบทที่มันอาศัยอยู่
②วัตถุทั่วโลกจะไม่ถูกต้องหากไม่ได้ดำเนินการ (อ้างอิง)
ตัวอย่างเช่น:
คัดลอกรหัสดังนี้: // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// วัตถุ JavaScript จะล้มเหลวเมื่อใด
-
ฟังก์ชั่น testobject () {
var _obj1 = วัตถุใหม่ ();
-
ฟังก์ชั่น testobject2 () {
var _obj2 = วัตถุใหม่ ();
return _obj2;
-
// ตัวอย่าง 1
testobject ();
// ตัวอย่าง 2
testobject2 ()
// ตัวอย่าง 3
var obj3 = testobject2 ();
obj3 = null;
// ตัวอย่าง 4
var obj4 = testobject2 ();
var arr = [obj4];
obj3 = null;
arr = [];
ในสี่ตัวอย่างนี้:
- "ตัวอย่าง 1" สร้าง _OBJ1 ในฟังก์ชัน testObject () แต่เมื่อฟังก์ชั่นออกมันจะออกจากบริบทของฟังก์ชั่นดังนั้น _OBJ1 จึงไม่ถูกต้อง
- ใน "ตัวอย่าง 2" วัตถุ _OBJ2 ก็ถูกสร้างขึ้นใน testObject2 () และผ่านออกไปดังนั้นวัตถุจึงมีสภาพแวดล้อมบริบท (และอายุการใช้งาน) "นอกฟังก์ชั่น" แต่เนื่องจากค่าคืนของฟังก์ชันไม่ได้ "ถือ" โดยตัวแปรอื่น ๆ _OBJ2 ไม่ถูกต้องทันที
- ใน "ตัวอย่างที่ 3" _OBJ2 ที่สร้างโดย testObject2 () ถูกจัดขึ้นโดยตัวแปรภายนอก OBJ3 ในเวลานี้จนกว่าบรรทัดของรหัส "obj3 = null" จะมีผล _obj2 จะไม่ถูกต้องเนื่องจากความสัมพันธ์อ้างอิงหายไป
- ด้วยเหตุผลเดียวกับในตัวอย่างที่ 3, _OBJ2 ใน "ตัวอย่าง 4" จะไม่ถูกต้องหลังจากบรรทัดของรหัส "arr = []"
อย่างไรก็ตาม "ความล้มเหลว" ของวัตถุไม่รอที่จะ "ปล่อย" ภายในรันไทม์ JavaScript ไม่มีวิธีที่จะบอกผู้ใช้อย่างแน่นอนว่า "เมื่อใดที่วัตถุจะถูกปล่อยออกมา" ขึ้นอยู่กับกลไกการกู้คืนหน่วยความจำของ JavaScript - กลยุทธ์นี้คล้ายกับกลไกการรีไซเคิลใน. NET
ในรหัสตัวอย่างการดำเนินการ Excel ก่อนหน้านี้เจ้าของวัตถุนั่นคือ "excel.exe" จะเกิดขึ้นหลังจาก "การเปิดตัวของอินสแตนซ์ออบเจ็กต์ ActiveX" เท่านั้น การล็อคไฟล์และข้อมูลรับรองการอนุญาตของระบบปฏิบัติการเกี่ยวข้องกับกระบวนการ ดังนั้นหากวัตถุนั้นเป็นเพียง "ล้มเหลว" และไม่ใช่ "ปล่อย" กระบวนการอื่น ๆ จะมีปัญหาเมื่อประมวลผลไฟล์และอ้างถึงข้อมูลรับรองการอนุญาตของระบบปฏิบัติการ
- บางคนบอกว่านี่เป็นข้อผิดพลาดในกลไก JavaScript หรือ COM จริงๆแล้วมันไม่ใช่ สิ่งนี้เกิดจากความสัมพันธ์ที่ซับซ้อนระหว่างระบบปฏิบัติการเช่น JavaScript แทนที่จะเป็นปัญหาอิสระ
Microsoft ได้เปิดเผยกลยุทธ์ในการแก้ปัญหานี้: เรียกกระบวนการรีไซเคิลหน่วยความจำเชิงรุก
กระบวนการ collectgarbage () (มักจะเรียกว่ากระบวนการ GC) มีให้ใน (Microsoft) JScript กระบวนการ GC ใช้ในการทำความสะอาด "การจัดแนววัตถุที่ล้มเหลว" ใน IE ปัจจุบันนั่นคือกระบวนการทำลายล้างของการเรียกวัตถุ
ในตัวอย่างข้างต้นรหัสที่เรียกขั้นตอน GC คือ:
คัดลอกรหัสดังนี้: // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// วิธีการเรียกใช้มาตรฐานของขั้นตอน GC เมื่อประมวลผลวัตถุ ActiveX
-
ฟังก์ชั่น writexls () {
//(เล็กน้อย...)
Excel.quit ();
excel = null;
settimeout (collectgarbage, 1);
-
บรรทัดแรกของรหัสเรียกวิธี excel.quit () เพื่อให้กระบวนการ Excel ยกเลิกและออก ในเวลานี้เนื่องจากสภาพแวดล้อม JavaScript มีอินสแตนซ์ของวัตถุ Excel กระบวนการ Excel ไม่ได้ยกเลิกจริง
บรรทัดที่สองของโค้ดทำให้ Excel เป็นโมฆะเพื่อล้างการอ้างอิงวัตถุดังนั้น "ทำให้เป็นโมฆะ" วัตถุ อย่างไรก็ตามเนื่องจากวัตถุยังคงอยู่ในบริบทของฟังก์ชั่นหากเรียกใช้ขั้นตอน GC โดยตรงวัตถุจะยังไม่ถูกทำความสะอาด
บรรทัดที่สามของรหัสใช้ settimeout () เพื่อเรียกใช้ฟังก์ชัน collectgarbage และช่วงเวลาถูกตั้งค่าเป็น '1' ซึ่งทำให้กระบวนการ GC เกิดขึ้นหลังจากฟังก์ชั่น writexls () เท่านั้น ด้วยวิธีนี้วัตถุ Excel ตรงกับสองเงื่อนไขของ "สามารถทำความสะอาดได้โดย GC": ไม่มีการอ้างอิงและออกจากบริบท
การใช้ขั้นตอน GC นั้นมีประสิทธิภาพมากในสภาพแวดล้อม JS โดยใช้วัตถุ ActiveX วัตถุ ActiveX ที่มีศักยภาพบางอย่าง ได้แก่ XML, VML, OWC (Office Web Componet), Flash และแม้แต่ Vbarray ใน JS
จากมุมมองนี้เนื่องจากสถาปัตยกรรม AJAX ใช้ XMLHTTP และยังต้องตอบสนองคุณสมบัติ "No Page Switching" การเรียกกระบวนการ GC ในเวลาที่เหมาะสมจะให้ประสบการณ์ที่ดีขึ้นโดยใช้ UI
ในความเป็นจริงแม้กับกระบวนการ GC ปัญหา Excel ดังกล่าวจะไม่ได้รับการแก้ไขอย่างสมบูรณ์ เพราะคือแคชข้อมูลรับรองการอนุญาต วิธีเดียวที่จะทำให้ข้อมูลรับรองการอนุญาตของหน้าเว็บได้รับการปรับปรุงคือ "เปลี่ยนเป็นหน้าใหม่" ดังนั้นในความเป็นจริงในโครงการ SPS ที่กล่าวถึงก่อนหน้านี้วิธีที่ฉันใช้ไม่ใช่ GC แต่รหัสต่อไปนี้:
คัดลอกรหัสดังนี้: // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// รหัสการสลับเพจที่ใช้เมื่อประมวลผลวัตถุ ActiveX
-
ฟังก์ชั่น writexls () {
//(เล็กน้อย...)
Excel.quit ();
excel = null;
// รหัสต่อไปนี้ใช้ในการแก้ข้อบกพร่องในการเรียก Excel วิธีการที่มีให้ใน MSDN:
// settimeout (collectgarbage, 1);
// เนื่องจากสถานะที่เชื่อถือได้ของหน้าเว็บไม่สามารถล้างได้ (หรือซิงโครไนซ์) จะทำให้ Saveas () และวิธีการอื่น ๆ
// ไม่ถูกต้องในครั้งต่อไปที่คุณเรียกมัน
location.reload ();
-
ในที่สุดโน้ตเสริมเกี่ยวกับ GC: เมื่อแบบฟอร์ม IE ลดลงเช่นจะเรียกมันอย่างแข็งขันหนึ่งครั้ง
ฟังก์ชั่น collectgarbage () สิ่งนี้ทำให้การใช้หน่วยความจำดีขึ้นอย่างมีนัยสำคัญหลังจากหน้าต่าง IE ลดลง
ฉันหวังว่าคำอธิบายในบทความนี้จะเป็นประโยชน์กับการเขียนโปรแกรมเว็บของทุกคนตาม JavaScript