求助:按Spreadsheet标签页顺序生成Web App图表及h1标题显示
问题解决思路
- 图表顺序不稳定的原因:原代码循环发起多个
google.script.run异步请求,请求返回顺序由服务器响应速度决定,导致图表渲染顺序随机。 - 核心解决方案:改为一次性从服务器获取所有目标工作表的完整数据(含标签页名称),再按标签页顺序依次渲染图表,确保显示顺序稳定。
- 添加h1服务名称:在渲染每个图表前,创建h1元素插入容器,内容使用对应工作表的名称。
修改后的代码
1. Code.gs 更新
替换原indicateursSFMC函数,新增批量获取数据的函数:
const classeur = SpreadsheetApp.getActiveSpreadsheet(); const fBDD = classeur.getSheetByName("BDD"); const fStaff = classeur.getSheetByName("Staff"); function doGet() { return HtmlService.createTemplateFromFile("Index").evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL); } function include(filename){ return HtmlService.createHtmlOutputFromFile(filename).getContent(); } // 新增:一次性获取前4个工作表的数据及名称 function getAllSheetData() { const classeurService = SpreadsheetApp.openById("1hqJ9WvlrWonsxAI5t4IvapL29JO1vBKCvDlfhKmSLIg"); const sheets = classeurService.getSheets().slice(0,4); return sheets.map(sheet => { const [[,...head], ...values] = sheet.getRange(1,1,sheet.getLastRow(),sheet.getLastColumn()).getValues().filter(d=>d[0] != ""); const obj = [...Map.groupBy(values, ([a]) => a)].reduce((o, [k, v]) => { const [,...data] = v[0].map((_, col) => v.map((row) => row[col] || null)); const [header,...rows] = data.map((r, i) => [(i == 0 ? "#" : head[i]),...r]); o[k] = { header, rows }; return o; }, {}); return { sheetName: sheet.getName(), chartData: obj[Object.keys(obj)[0]] }; }); }
2. JavaScript.html 更新
修改图表渲染逻辑,按顺序生成h1标题和图表:
<script src="https://cdn.anychart.com/releases/8.13.0/js/anychart-core.min.js"></script> <script src="https://cdn.anychart.com/releases/8.13.0/js/anychart-radar.min.js"></script> <script> function loadView(options){ var id = typeof options.id === "undefined" ? "app" : options.id; var cb = typeof options.callback === "undefined" ? function(){} : options.callback; } function loadGraphicsMC(){ loadView({func: "loadSearchView", callback: showGraphicsMC()}); } function showGraphicsMC(){ // 一次性获取所有工作表数据 google.script.run.withSuccessHandler(allSheetData => { const container = document.getElementById("divGraphiquesMC"); allSheetData.forEach((item, index) => { // 创建h1标签显示服务名称 const titleEl = document.createElement("h1"); titleEl.textContent = item.sheetName; container.appendChild(titleEl); // 确定图表副标题 const titre = index % 2 === 1 ? "Big Skill 2" : "Big Skill 1"; // 渲染图表到独立div const chartDiv = document.createElement("div"); container.appendChild(chartDiv); graphiqueMC(item.chartData, chartDiv, titre); }); }).getAllSheetData(); } function isOdd(num) { return num % 2;} function graphiqueMC(chartData,divContainer,titre) { var chart = anychart.radar(); chart.defaultSeriesType('line'); chart.data(chartData); chart.palette(['#ffcc99', '#ffcccc', '#ff99cc', '#cc99ff', '#ccccff', '#99ccff', '#baf4f4', '#99ffcc', '#ccffcc', '#ccff99']); chart.yAxis().stroke('#545f69'); chart.yAxis().ticks().stroke('#545f69'); chart.yGrid().palette(['gray 0.05', 'gray 0.025']); chart.yScale().ticks().interval(1); chart.yScale().minimum(0); chart.yScale().maximum(5); chart.xGrid().stroke({ color: "#545f69", thickness: 0.5, dash: "10 5" }); chart.interactivity().hoverMode('by-x'); var background = chart.background(); background.stroke("3 #0d5973"); background.cornerType("round"); background.corners(20); chart.markerPalette(['round']); chart.tooltip() .displayMode('union') .useHtml(true) .format(function (e) { return '<span style="color:' + this.series.color() + '">' + this.seriesName + ": " + this.value + "</span>" }); chart.legend() .align('center') .position('center-bottom') .enabled(true); chart.title(titre); chart.container(divContainer); chart.draw(); } </script>
关键修改说明
- 批量获取数据:通过
getAllSheetData一次性拉取所有目标工作表的信息,避免异步请求顺序混乱。 - 顺序渲染:遍历返回的数组,严格按工作表顺序生成h1标题和图表,确保显示顺序与标签页一致。
- 独立容器:每个图表使用单独的div,避免多个图表渲染到同一容器导致的布局冲突。
- h1标题:直接使用工作表名称作为h1内容,满足服务名称展示需求。
内容的提问来源于stack exchange,提问作者GowlDesign
相关产品推荐
相关产品推荐

