将无序列表 (<ul>) 转换为 HTML 格式的表格 (<table>)
Convert unordered lists (<ul>) into HTML-formatted tables (<table>)
我之前一直在寻求一种解决方案,使我能够将无序列表转换为格式化的 HTML table.
当时好心的用户提出了解决方案,我附在下面。
该解决方案将无序列表变成 Google 工作表中的常规 table,其中不同的值被划分到它们自己的单元格中。相反,我希望将无序列表转换为仅放置在一个单元格中的格式化 html table 列表。
如果可能的话,除此之外,我希望能够将数百个无序列表放入脚本中,然后将其转换为各自的 HTML 格式 table .
在下面查看我从另一个用户那里得到的以前的解决方案。
希望一切都有意义。
编辑:
我还在这个 post.
的最底部添加了输入和首选输出
In your situation, how about the following sample script?
Sample script 1:
This script parses your value using the regex.
function myFunction1() {
// This sample value is from your question.
const sample = `<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Water column pressure: 4000mm</li>
<li>Fit: Regular unisex</li>
<li>Elasticated waistband with drawstring</li>
<li>Elasticated cuffs with tonal coated zips</li>
<li>Single back pocket with eyelet</li>
<li>Concealed side pockets</li>
<li>Ultrasonically welded seams</li>
<li>Reflective accents</li>
</ul>`;
// Parse list.
const obj = sample.matchAll(/<li>([\w\S\s]+?)<\/li>/g);
const values = [...obj].map(e => {
if (e && e.length > 1) {
const temp = e[1].split(":");
return temp.length == 1 ? [temp[0].trim(), ""] : temp.map(f => f.trim());
}
return ["", ""];
});
// Put the values to the sheet.
const sheetName = "Sheet1"; // Please set the sheet name.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
When this script is run, your sample value is parsed. And, the values are put to the sheet.
Sample script 2:
This script parses your value using XmlService.
function myFunction1() {
// This sample value is from your question.
const sample = `<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Water column pressure: 4000mm</li>
<li>Fit: Regular unisex</li>
<li>Elasticated waistband with drawstring</li>
<li>Elasticated cuffs with tonal coated zips</li>
<li>Single back pocket with eyelet</li>
<li>Concealed side pockets</li>
<li>Ultrasonically welded seams</li>
<li>Reflective accents</li>
</ul>`;
// Parse list.
const root = XmlService.parse(sample).getRootElement();
const values = root.getChildren("li", root.getNamespace()).map(e => {
const temp = e.getValue().split(":");
return temp.length == 1 ? [temp[0].trim(), ""] : temp.map(f => f.trim());
});
// Put the values to the sheet.
const sheetName = "Sheet1"; // Please set the sheet name.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
References:
map()
setValues(values)
Added:
From your following additional question,
That does the job for doing it on one single product. Let's say I have a batch of product details for several different products. Like here below. Is there a way to run the script on all three at once so it becomes three different tables?
In this case, how about the following sample script?
Sample script:
function myFunction2() {
// This is from your new question.
const samples = [
"<ul><li>Material: 100% polyester with polyurethane coating</li><li>Lining: 100% polyester</li><li>Insulation: 100% polyester</li><li>Measurements: H160cm x W140cm x D1cm / H63 x W55.1 x 0.4 inches</li><li>When packed: H13cm x W47cm x D25cm / H5.1 x W18.5 x D9.8 inc </li><li>Pack-carry-store system with buckles and adjustable webbing straps</li><li>Soft, quilted and padded side</li><li>Waterproof upper on reverse</li></ul>",
"<ul><li>Material: 100% polyester with polyurethane coating</li><li>Water column pressure: 4000mm</li><li>Soft mesh lining</li><li>Circumference: S1 – 61.5 cm / 24.2 inches, / S2 - 66 cm / 26 inches</li></ul>",
"<ul><li>Material: 100% polyester with polyurethane coating</li><li>Lining: 100% polyester </li><li>Water column pressure: 8000mm</li><li>Measurements: H16 x W21 x D8.5cm / H6.3 x W8.3 x D3.3 inches</li><li>Volume: 3 liters / 0.8 gallons</li><li>Coated tonal zip closure</li><li>Single main compartment </li><li>Detachable adjustable webbing shoulder strap </li><li>Carry handle</li></ul>"
];
const sheetNames = ["Sheet1", "Sheet2", "Sheet3"]; // Please set the sheet names.
samples.forEach((sample, i) => {
const root = XmlService.parse(sample).getRootElement();
const values = root.getChildren("li", root.getNamespace()).map(e => {
const temp = e.getValue().split(":");
return temp.length == 1 ? [temp[0].trim(), ""] : temp.map(f => f.trim());
});
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetNames[i]);
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
});
}
请在下方查看输入和首选输出。
每当有一行带冒号的文本,比如“Material: 100% polyester with polyurethane coating”,我希望它在 table 中分成两列,因此“Material:”在第 1 列中,“100% 聚酯与聚氨酯涂层”在第 2 列中。
输入:
/** List 1 **/
<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Lining: 100% polyester</li>
<li>Insulation: 100% polyester</li>
<li>Measurements: H160cm x W140cm x D1cm / H63 x W55.1 x 0.4 inches</li>
<li>When packed: H13cm x W47cm x D25cm / H5.1 x W18.5 x D9.8 inc </li>
<li>Pack-carry-store system with buckles and adjustable webbing straps</li>
<li>Soft, quilted and padded side</li>
<li>Waterproof upper on reverse</li>
</ul>
/** List 2 **/
<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Water column pressure: 4000mm</li>
<li>Circumference: S1 – 61.5 cm / 24.2 inches, / S2 - 66 cm / 26 inches</li>
<li>Soft mesh lining</li>
</ul>
/** List 3 **/
<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Lining: 100% polyester </li>
<li>Water column pressure: 8000mm</li>
<li>Measurements: H16 x W21 x D8.5cm / H6.3 x W8.3 x D3.3 inches</li>
<li>Volume: 3 liters / 0.8 gallons</li>
<li>Coated tonal zip closure</li>
<li>Single main compartment </li>
<li>Detachable adjustable webbing shoulder strap </li>
<li>Carry handle</li>
</ul>
想要的输出:
/** Table 1 (converted from List 1) **/
<table>
<tbody>
<tr>
<td>Material:</td>
<td>100% polyester with polyurethane coating</td>
</tr>
<tr>
<td>Lining:</td>
<td>100% polyester</td>
</tr>
<tr>
<td>Insulation:</td>
<td>100% polyester</td>
</tr>
<tr>
<td>Measurements:</td>
<td>H160cm x W140cm x D1cm / H63 x W55.1 x 0.4 inches</td>
</tr>
<tr>
<td>When packed:</td>
<td>H13cm x W47cm x D25cm / H5.1 x W18.5 x D9.8 inc</td>
</tr>
<tr>
<td>Pack-carry-store system with buckles and adjustable webbing straps</td>
<td></td>
</tr>
<tr>
<td>Soft, quilted and padded side</td>
<td></td>
</tr>
<tr>
<td>Waterproof upper on reverse</td>
<td></td>
</tr>
</tbody>
</table>
/** Table 2 (converted from List 2) **/
<table>
<tbody>
<tr>
<td>Material:</td>
<td>100% polyester with polyurethane coating</td>
</tr>
<tr>
<td>Water column pressure:</td>
<td>4000mm</td>
</tr>
<tr>
<td>Circumference:</td>
<td>S1 – 61.5 cm / 24.2 inches, / S2 - 66 cm / 26 inches</td>
</tr>
<tr>
<td>Soft mesh lining</td>
<td></td>
</tr>
</tbody>
</table>
/** Table 3 (converted from List 3) **/
<table>
<tbody>
<tr>
<td>Material:</td>
<td>100% polyester with polyurethane coating</td>
</tr>
<tr>
<td>Lining:</td>
<td>100% polyester</td>
</tr>
<tr>
<td>Water column pressure:</td>
<td>8000mm</td>
</tr>
<tr>
<td>Measurements:</td>
<td>H16 x W21 x D8.5cm / H6.3 x W8.3 x D3.3 inches</td>
</tr>
<tr>
<td>Volume:</td>
<td>3 liters / 0.8 gallons</td>
</tr>
<tr>
<td>Coated tonal zip closure</td>
<td></td>
</tr>
<tr>
<td>Single main compartment</td>
<td></td>
</tr>
<tr>
<td>Detachable adjustable webbing shoulder strap</td>
<td></td>
</tr>
<tr>
<td>Carry handle</td>
<td></td>
</tr>
</tbody>
</table>
尝试
function myFunc() {
const sample = `<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Water column pressure: 4000mm</li>
<li>Fit: Regular unisex</li>
<li>Elasticated waistband with drawstring</li>
<li>Elasticated cuffs with tonal coated zips</li>
<li>Single back pocket with eyelet</li>
<li>Concealed side pockets</li>
<li>Ultrasonically welded seams</li>
<li>Reflective accents</li>
</ul>`;
const result = sample.replace(/<li>|<ul>|<\/li>|<\/ul>/g,'')
const sheetName = "Sheet1"; // Please set the sheet name.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
sheet.getRange(1, 1).setValue(result);
}
列表将只放在一个单元格中
对于这种情况,我建议尝试使用这样的自定义公式:
function to_table(range) {
const do_replace = text => text
.replace(/<ul>/g, '<table>')
.replace(/<\/ul>/g, '</table>')
.replace(/<li>/g, ' <tr>\n <td>')
.replace(/<\/li>/g, '</td>\n </tr>')
.replace(/: /g, ':</td>\n <td>')
.replace(/(<tr>\n <td>.+?<\/td>\n)( <\/tr>)/gm, ' <td></td>\n');
try { return range.map(row => do_replace(row[0])) } // for a range
catch(e) { return do_replace(range) } // for a single cell
}
要处理单个单元格:
要处理整列:
我之前一直在寻求一种解决方案,使我能够将无序列表转换为格式化的 HTML table.
当时好心的用户提出了解决方案,我附在下面。
该解决方案将无序列表变成 Google 工作表中的常规 table,其中不同的值被划分到它们自己的单元格中。相反,我希望将无序列表转换为仅放置在一个单元格中的格式化 html table 列表。
如果可能的话,除此之外,我希望能够将数百个无序列表放入脚本中,然后将其转换为各自的 HTML 格式 table .
在下面查看我从另一个用户那里得到的以前的解决方案。
希望一切都有意义。
编辑: 我还在这个 post.
的最底部添加了输入和首选输出In your situation, how about the following sample script?
Sample script 1:
This script parses your value using the regex.
function myFunction1() {
// This sample value is from your question.
const sample = `<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Water column pressure: 4000mm</li>
<li>Fit: Regular unisex</li>
<li>Elasticated waistband with drawstring</li>
<li>Elasticated cuffs with tonal coated zips</li>
<li>Single back pocket with eyelet</li>
<li>Concealed side pockets</li>
<li>Ultrasonically welded seams</li>
<li>Reflective accents</li>
</ul>`;
// Parse list.
const obj = sample.matchAll(/<li>([\w\S\s]+?)<\/li>/g);
const values = [...obj].map(e => {
if (e && e.length > 1) {
const temp = e[1].split(":");
return temp.length == 1 ? [temp[0].trim(), ""] : temp.map(f => f.trim());
}
return ["", ""];
});
// Put the values to the sheet.
const sheetName = "Sheet1"; // Please set the sheet name.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
When this script is run, your sample value is parsed. And, the values are put to the sheet.
Sample script 2:
This script parses your value using XmlService.
function myFunction1() {
// This sample value is from your question.
const sample = `<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Water column pressure: 4000mm</li>
<li>Fit: Regular unisex</li>
<li>Elasticated waistband with drawstring</li>
<li>Elasticated cuffs with tonal coated zips</li>
<li>Single back pocket with eyelet</li>
<li>Concealed side pockets</li>
<li>Ultrasonically welded seams</li>
<li>Reflective accents</li>
</ul>`;
// Parse list.
const root = XmlService.parse(sample).getRootElement();
const values = root.getChildren("li", root.getNamespace()).map(e => {
const temp = e.getValue().split(":");
return temp.length == 1 ? [temp[0].trim(), ""] : temp.map(f => f.trim());
});
// Put the values to the sheet.
const sheetName = "Sheet1"; // Please set the sheet name.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
References:
map()
setValues(values)
Added:
From your following additional question,
That does the job for doing it on one single product. Let's say I have a batch of product details for several different products. Like here below. Is there a way to run the script on all three at once so it becomes three different tables?
In this case, how about the following sample script?
Sample script:
function myFunction2() {
// This is from your new question.
const samples = [
"<ul><li>Material: 100% polyester with polyurethane coating</li><li>Lining: 100% polyester</li><li>Insulation: 100% polyester</li><li>Measurements: H160cm x W140cm x D1cm / H63 x W55.1 x 0.4 inches</li><li>When packed: H13cm x W47cm x D25cm / H5.1 x W18.5 x D9.8 inc </li><li>Pack-carry-store system with buckles and adjustable webbing straps</li><li>Soft, quilted and padded side</li><li>Waterproof upper on reverse</li></ul>",
"<ul><li>Material: 100% polyester with polyurethane coating</li><li>Water column pressure: 4000mm</li><li>Soft mesh lining</li><li>Circumference: S1 – 61.5 cm / 24.2 inches, / S2 - 66 cm / 26 inches</li></ul>",
"<ul><li>Material: 100% polyester with polyurethane coating</li><li>Lining: 100% polyester </li><li>Water column pressure: 8000mm</li><li>Measurements: H16 x W21 x D8.5cm / H6.3 x W8.3 x D3.3 inches</li><li>Volume: 3 liters / 0.8 gallons</li><li>Coated tonal zip closure</li><li>Single main compartment </li><li>Detachable adjustable webbing shoulder strap </li><li>Carry handle</li></ul>"
];
const sheetNames = ["Sheet1", "Sheet2", "Sheet3"]; // Please set the sheet names.
samples.forEach((sample, i) => {
const root = XmlService.parse(sample).getRootElement();
const values = root.getChildren("li", root.getNamespace()).map(e => {
const temp = e.getValue().split(":");
return temp.length == 1 ? [temp[0].trim(), ""] : temp.map(f => f.trim());
});
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetNames[i]);
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
});
}
请在下方查看输入和首选输出。
每当有一行带冒号的文本,比如“Material: 100% polyester with polyurethane coating”,我希望它在 table 中分成两列,因此“Material:”在第 1 列中,“100% 聚酯与聚氨酯涂层”在第 2 列中。
输入:
/** List 1 **/
<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Lining: 100% polyester</li>
<li>Insulation: 100% polyester</li>
<li>Measurements: H160cm x W140cm x D1cm / H63 x W55.1 x 0.4 inches</li>
<li>When packed: H13cm x W47cm x D25cm / H5.1 x W18.5 x D9.8 inc </li>
<li>Pack-carry-store system with buckles and adjustable webbing straps</li>
<li>Soft, quilted and padded side</li>
<li>Waterproof upper on reverse</li>
</ul>
/** List 2 **/
<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Water column pressure: 4000mm</li>
<li>Circumference: S1 – 61.5 cm / 24.2 inches, / S2 - 66 cm / 26 inches</li>
<li>Soft mesh lining</li>
</ul>
/** List 3 **/
<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Lining: 100% polyester </li>
<li>Water column pressure: 8000mm</li>
<li>Measurements: H16 x W21 x D8.5cm / H6.3 x W8.3 x D3.3 inches</li>
<li>Volume: 3 liters / 0.8 gallons</li>
<li>Coated tonal zip closure</li>
<li>Single main compartment </li>
<li>Detachable adjustable webbing shoulder strap </li>
<li>Carry handle</li>
</ul>
想要的输出:
/** Table 1 (converted from List 1) **/
<table>
<tbody>
<tr>
<td>Material:</td>
<td>100% polyester with polyurethane coating</td>
</tr>
<tr>
<td>Lining:</td>
<td>100% polyester</td>
</tr>
<tr>
<td>Insulation:</td>
<td>100% polyester</td>
</tr>
<tr>
<td>Measurements:</td>
<td>H160cm x W140cm x D1cm / H63 x W55.1 x 0.4 inches</td>
</tr>
<tr>
<td>When packed:</td>
<td>H13cm x W47cm x D25cm / H5.1 x W18.5 x D9.8 inc</td>
</tr>
<tr>
<td>Pack-carry-store system with buckles and adjustable webbing straps</td>
<td></td>
</tr>
<tr>
<td>Soft, quilted and padded side</td>
<td></td>
</tr>
<tr>
<td>Waterproof upper on reverse</td>
<td></td>
</tr>
</tbody>
</table>
/** Table 2 (converted from List 2) **/
<table>
<tbody>
<tr>
<td>Material:</td>
<td>100% polyester with polyurethane coating</td>
</tr>
<tr>
<td>Water column pressure:</td>
<td>4000mm</td>
</tr>
<tr>
<td>Circumference:</td>
<td>S1 – 61.5 cm / 24.2 inches, / S2 - 66 cm / 26 inches</td>
</tr>
<tr>
<td>Soft mesh lining</td>
<td></td>
</tr>
</tbody>
</table>
/** Table 3 (converted from List 3) **/
<table>
<tbody>
<tr>
<td>Material:</td>
<td>100% polyester with polyurethane coating</td>
</tr>
<tr>
<td>Lining:</td>
<td>100% polyester</td>
</tr>
<tr>
<td>Water column pressure:</td>
<td>8000mm</td>
</tr>
<tr>
<td>Measurements:</td>
<td>H16 x W21 x D8.5cm / H6.3 x W8.3 x D3.3 inches</td>
</tr>
<tr>
<td>Volume:</td>
<td>3 liters / 0.8 gallons</td>
</tr>
<tr>
<td>Coated tonal zip closure</td>
<td></td>
</tr>
<tr>
<td>Single main compartment</td>
<td></td>
</tr>
<tr>
<td>Detachable adjustable webbing shoulder strap</td>
<td></td>
</tr>
<tr>
<td>Carry handle</td>
<td></td>
</tr>
</tbody>
</table>
尝试
function myFunc() {
const sample = `<ul>
<li>Material: 100% polyester with polyurethane coating</li>
<li>Water column pressure: 4000mm</li>
<li>Fit: Regular unisex</li>
<li>Elasticated waistband with drawstring</li>
<li>Elasticated cuffs with tonal coated zips</li>
<li>Single back pocket with eyelet</li>
<li>Concealed side pockets</li>
<li>Ultrasonically welded seams</li>
<li>Reflective accents</li>
</ul>`;
const result = sample.replace(/<li>|<ul>|<\/li>|<\/ul>/g,'')
const sheetName = "Sheet1"; // Please set the sheet name.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
sheet.getRange(1, 1).setValue(result);
}
列表将只放在一个单元格中
对于这种情况,我建议尝试使用这样的自定义公式:
function to_table(range) {
const do_replace = text => text
.replace(/<ul>/g, '<table>')
.replace(/<\/ul>/g, '</table>')
.replace(/<li>/g, ' <tr>\n <td>')
.replace(/<\/li>/g, '</td>\n </tr>')
.replace(/: /g, ':</td>\n <td>')
.replace(/(<tr>\n <td>.+?<\/td>\n)( <\/tr>)/gm, ' <td></td>\n');
try { return range.map(row => do_replace(row[0])) } // for a range
catch(e) { return do_replace(range) } // for a single cell
}
要处理单个单元格:
要处理整列: