คุณต้องการแปลงไฟล์ CSV ขนาดใหญ่เป็นสเปรดชีตแบบแยก หากความเข้าใจของฉันถูกต้อง วิธีแก้ปัญหานี้เป็นอย่างไร
ปัญหาและวิธีแก้ปัญหาสำหรับสถานการณ์นี้:
เมื่อไฟล์ CSV ขนาดใหญ่ถูกแปลงเป็นสเปรดชีต ไฟล์ดังกล่าวจะไม่สามารถแปลงเป็นสเปรดชีตได้โดยตรง เนื่องจากมีทั้งจำนวนเซลล์ทั้งหมดและขนาดไฟล์ และเมื่อพยายามแยกไฟล์ขนาดใหญ่ มันก็ไม่สามารถทำได้เนื่องจาก Blob ที่สามารถใช้ใน GAS มีขนาดน้อยกว่า 50 MB (52,428,800 ไบต์)
ในสภาพแวดล้อมของฉัน เมื่อใช้ไฟล์ CSV ขนาด 100 MB สำหรับสคริปต์ตัวอย่างนี้ เมื่อไฟล์ถูกแบ่งออกเป็น 10 MB จะใช้เวลาประมาณ 65 วินาทีในการแปลงก้อนข้อมูลเป็นสเปรดชีต ในกรณีนี้ เมื่อไฟล์ CSV ถูกแปลงอย่างสมบูรณ์ จะถือว่าไฟล์นั้นเกินเวลาที่กำหนด (6 นาที) ในการดำเนินการ GAS
- In order to avoid this, it is required to implement the resumable conversion from the large CSV-file to several spreadsheets.
เตรียมตัว :
หากต้องการใช้สคริปต์ตัวอย่างนี้ โปรดเปิดใช้งาน Drive API ที่ Advanced Google Services และคอนโซล API
เปิดใช้งาน Drive API v2 ที่บริการขั้นสูงของ Google
- On script editor
- Resources -> Advanced Google Services
- เปิด Drive API เวอร์ชัน 2
- On script editor
- Resources -> Cloud Platform project
- ดูคอนโซล API
- ที่เริ่มต้นใช้งาน คลิกเปิดใช้งาน API และรับข้อมูลรับรอง เช่น คีย์
- ที่ด้านซ้าย คลิกไลบรารี
- ที่ Search for APIs & services ให้ใส่ "Drive" และคลิก Drive API
- คลิกปุ่มเปิดใช้งาน
- หากเปิดใช้งาน API แล้ว โปรดอย่าปิด
สคริปต์ตัวอย่าง:
function createSplitSpreadsheet(obj) {
var accessToken = ScriptApp.getOAuthToken();
var baseUrl = "https://www.googleapis.com/drive/v3/files/";
// Retrieve file size.
var url1 = baseUrl + obj.fileId + "?fields=size";
var params1 = {
method: "get",
headers: {Authorization: "Bearer " + accessToken},
};
var fileSize = Number(JSON.parse(UrlFetchApp.fetch(url1, {headers: {Authorization: "Bearer " + accessToken}}).getContentText()).size);
// Calculate number of output files.
if (obj.files == null) {
obj.number = 1;
obj.start = 0;
}
var start = obj.start;
var end = start + obj.chunk;
var useFileSize = fileSize - start;
f = Math.floor(useFileSize / obj.chunk);
f = useFileSize % obj.chunk > 0 ? f + 1 : f;
if (f < obj.files || obj.files == null) {
obj.files = f;
}
// Split large file by chunk size (bytes).
var url2 = baseUrl + obj.fileId + "?alt=media";
var i;
for (i = 0; i < obj.files; i++) {
var params = {
method: "get",
headers: {
Authorization: "Bearer " + accessToken,
Range: "bytes=" + start + "-" + end,
},
};
var res = UrlFetchApp.fetch(url2, params).getContentText();
var e = res.lastIndexOf("\n");
start += e + 1;
end = start + obj.chunk;
Drive.Files.insert(
{mimeType: MimeType.GOOGLE_SHEETS, title: obj.fileName + (i + obj.number)},
Utilities.newBlob(res.substr(0, e), MimeType.CSV)
);
}
// Return next start value if there is a next chunk for the resume.
if (start < fileSize) {
return {nextStart: start, nextNumber: i + obj.number};
} else {
return null;
}
}
// Please run this function.
function main() {
var obj = {
fileId: "#####", // File ID of the large CSV file.
chunk: 10485760, // 10MB Please modify this for your situation.
files: 3, // Please input the number of files you want to convert.
start: 0,
fileName: "sample",
number: 1, // Counter of output files. Please input this as a next number.
};
var nextStart = createSplitSpreadsheet(obj);
Logger.log(nextStart);
}
การใช้งาน :
เมื่อคุณใช้สิ่งนี้ โปรดแก้ไข obj
ใน main()
สำหรับสถานการณ์ของคุณ และเรียกใช้ main()
กรณีตัวอย่างมีดังนี้
ก็ประมาณนี้ครับ.
- คุณต้องการแปลงไฟล์ CSV ที่มีขนาด 100 MB เป็น 10 สเปรดชีต
- ขนาดของหนึ่งชิ้นคือ 10 MB
- ไฟล์ CSV จะถูกประมวลผลทุกๆ 3 ครั้ง
ในกรณีตัวอย่างนี้ แต่ละ obj
จะเป็นดังนี้ โปรดป้อน obj
แต่ละตัวในการรันแต่ละครั้ง
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: 0, fileName: "sample", number: 1}
{"nextStart": ### nextStart2 ###, "nextNumber": 4}
is returned from createSplitSpreadsheet()
.
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart2 ###, fileName: "sample", number: 4}
{"nextStart": ### nextStart3 ###, "nextNumber": 7}
is returned from createSplitSpreadsheet()
.
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart3 ###, fileName: "sample", number: 7}
{"nextStart": ### nextStart4 ###, "nextNumber": 10}
is returned from createSplitSpreadsheet()
.
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart4 ###, fileName: "sample", number: 10}
null
is returned from createSplitSpreadsheet()
.
ในขั้นตอนนี้ จะมีการสร้างสเปรดชีต 10 รายการจากไฟล์ CSV ที่มีขนาด 100 MB
หากใช้ null
สำหรับ files
ใน obj
ระบบจะคำนวณ files
โดยอัตโนมัติ แต่ในกรณีนี้ ระยะเวลาที่จำกัดในการดำเนินการ GAS อาจสิ้นสุดลงแล้ว โปรดระวังสิ่งนี้
อ้างอิง :
ถ้านี่ไม่ใช่สิ่งที่คุณต้องการ ฉันขอโทษ
person
Tanaike
schedule
26.06.2018