在上一篇文章中,我能够实现部分目标,但我遇到了数据问题。该脚本旨在创建 CSV 导出,其中根据标题值导出特定数据列,并在导出的数据中更改标题值。
例如,我想从标题为“产品名称 - 完整”的列中导出列数据,但在导出中我需要将标题“产品名称 - 完整”更改为“描述 1”。
出现的问题是我有多个字段包含标点符号,例如逗号、引号等,目前引号会导致错误。该脚本将第一个引号更改为 ï,然后如果有第二个引号,则会将数据推送到下一列。
这里是测试工作簿的链接。脚本如下。
function Export_Database() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Database');
var folderTime = Utilities.formatDate(new Date(), "GMT-8", "yyyy-MM-dd'_'HH:mm:ss") // Logger 1-3
var folder = DriveApp.createFolder(ss.getName().toLowerCase().replace(/ /g,'_') + '_csv_' + folderTime);
var fileName = sheet.getName() + ".csv";
var csvFile = Convert_Database(fileName, sheet); //****REF
var file = folder.createFile(fileName, csvFile);
var downloadURL = file.getDownloadUrl().slice(0, -8);
Export_DatabaseURL(downloadURL); //****REF
//1 Logger.log("DEBUG: Folder date = "+folderTime) // DEBUG
//2 Logger.log("DEBUG: Proposed folder name: "+ss.getName().toLowerCase().replace(/ /g,'_') + '_csv_' + folderTime) // DEBUG
//3 Logger.log("DEBUG: Proposed file name: "+sheet.getName() + ".csv") // DEBUG
}
function Export_DatabaseURL(downloadURL) { //****REF
var link = HtmlService.createHtmlOutput('<a href="' + downloadURL + '">Click here to download</a>');
SpreadsheetApp.getUi().showModalDialog(link, 'Your CSV file is ready!');
}
function Convert_Database(csvFileName, sheet) {
const wb = SpreadsheetApp.getActiveSpreadsheet();
const sh = wb.getSheetByName("Database");
const allvalues = sh.getRange(1,1,sh.getLastRow(),sh.getLastColumn()).getValues() // Logger 1 | Get values (Row,Column,OptNumRows,OptNumColumns)
const header1 = allvalues[0].indexOf("SKU") // get the column Index of the headers
const header2 = allvalues[0].indexOf("Product Name - Full")
const header3 = allvalues[0].indexOf("Date Updated")
const header4 = allvalues[0].indexOf("Purchase Unit")
const header5 = allvalues[0].indexOf("PRICE1")
const header6 = allvalues[0].indexOf("Conversion")
const header7 = allvalues[0].indexOf("Delivery Product Name")
const header8 = allvalues[0].indexOf("Delivery Product Description")
allvalues[0][header2] = "Description 1" // Assign replacement values
allvalues[0][header3] = "Date"
allvalues[0][header4] = "P. Unit"
allvalues[0][header5] = "Price 1"
allvalues[0][header6] = "Conv"
allvalues[0][header7] = "Short Description"
allvalues[0][header7] = "Long Description"
// extract only the columns that relate to the headers
var data = allvalues.map(function(o){return [
o[header1],o[header2],o[header3],o[header4],o[header5],o[header6],o[header7],o[header8]
]})
// convert double quotes to unicode
//loop over the rows in the array
for (var row in data) {
//use Array.map to execute a replace call on each of the cells in the row.
var data_values = data[row].map(function(original_datavalue) {
return original_datavalue.toString().replace('"', '"');
})
//replace the original row values with the replaced values
data[row] = data_values;
}
// wrap any value containing a comma in double quotes
data = data.map(function(e) {return e.map(function(f) {return ~f.indexOf(",") ? '"' + f + '"' : f})})
// Logger.log("data rows = "+data.length+", data columns = "+data[0].length)
var csvFile = undefined
// loop through the data in the range and build a string with the csv data
if (data.length > 1) {
var csv = "";
for (var dataRow = 0; dataRow < data.length; dataRow++) {
// join each row's columns
// add a carriage return to end of each row, except for the last one
if (dataRow < data.length-1) {
// valid data row
csv += data[dataRow].join(",") + "\r\n";
//Logger.log("DEBUG: row#"+dataRow+", csv = "+data[dataRow].join(",") + "\r\n")
}
else {
csv += data[dataRow];
}
}
csvFile = csv;
}
return csvFile;
}
在您的情况下,作为一个简单的修改,如何使用端点将工作表转换为 CSV 数据?当这反映在您的放映脚本中时,它会变成如下所示。
请修改您的函数
Convert_Database
如下。
function Convert_Database(csvFileName, sheet) {
const wb = SpreadsheetApp.getActiveSpreadsheet();
const sh = wb.getSheetByName("Database");
const allvalues = sh.getRange(1, 1, sh.getLastRow(), sh.getLastColumn()).getValues();
const header1 = allvalues[0].indexOf("SKU");
const header2 = allvalues[0].indexOf("Product Name - Full");
const header3 = allvalues[0].indexOf("Date Updated");
const header4 = allvalues[0].indexOf("Purchase Unit");
const header5 = allvalues[0].indexOf("PRICE1");
const header6 = allvalues[0].indexOf("Conversion");
const header7 = allvalues[0].indexOf("Delivery Product Name");
const header8 = allvalues[0].indexOf("Delivery Product Description");
allvalues[0][header2] = "Description 1";
allvalues[0][header3] = "Date";
allvalues[0][header4] = "P. Unit";
allvalues[0][header5] = "Price 1";
allvalues[0][header6] = "Conv";
allvalues[0][header7] = "Short Description";
allvalues[0][header7] = "Long Description";
var data = allvalues.map(function (o) { return [o[header1], o[header2], o[header3], o[header4], o[header5], o[header6], o[header7], o[header8]] });
// --- I modified the below script.
const temp = wb.insertSheet();
temp.getRange(1, 1, data.length, data[0].length).setValues(data.map(r => r.map(c => c instanceof Date ? c.toString() : c)));
SpreadsheetApp.flush();
const url = `https://docs.google.com/spreadsheets/export?id=${wb.getId()}&exportFormat=csv&gid=${temp.getSheetId()}`;
const csvFile = UrlFetchApp.fetch(url, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } }).getContentText();
wb.deleteSheet(temp);
return csvFile;
}
data.map(r => r.map(c => c instanceof Date ? c.toString() : c))
修改为date
。csvFileName, sheet
的值。