You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Google Sheets数据动态填充Google Doc多页每份4个表单的实现问题

实现方案

核心思路

  • 提前存储原始模板的完整内容结构,每次新增页面时直接复用该结构生成新的占位符组
  • 每填充完4条数据后,判断是否还有剩余未处理数据,如有则插入分页符并追加新的模板内容
  • 最后处理不足4条数据的剩余占位符,避免原始占位符文本残留

修改后的完整代码

function onOpen() {
    const ui = SpreadsheetApp.getUi();
    const menu = ui.createMenu('Auto Fill');
    menu.addItem('Create Delivery Slips', 'createNewDeliverySlips');
    menu.addToUi();
}

function createNewDeliverySlips() {
    const googleDocTemplate = DriveApp.getFileById('<替换为模板文件ID>');
    const googleDocFolder = DriveApp.getFolderById('<替换为目标文件夹ID>');
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
    const rows = sheet.getDataRange().getValues();

    // 新增:获取原始模板的完整内容结构,用于后续新页面复用
    const originalTemplateDoc = DocumentApp.openById(googleDocTemplate.getId());
    const templateBody = originalTemplateDoc.getBody();
    const templateContent = templateBody.copy();
    originalTemplateDoc.saveAndClose();

    const copy = googleDocTemplate.makeCopy(`Delivery Slips`, googleDocFolder);
    const doc = DocumentApp.openById( copy.getId() );
    const body = doc.getBody();

    rows.forEach( function( row, index ) {
        if (index === 0) return;

        if (index % 4 === 1){
            body.replaceText('{{First Name1}}', row[1]);
            body.replaceText('{{Last Name1}}', row[2]);
            body.replaceText('{{Address1}}', row[3]);
            body.replaceText('{{City1}}', row[4]);
            body.replaceText('{{State1}}', row[5]);
            body.replaceText('{{Zip1}}', row[6]);
        }

        if (index % 4 === 2){
            body.replaceText('{{First Name2}}', row[1]);
            body.replaceText('{{Last Name2}}', row[2]);
            body.replaceText('{{Address2}}', row[3]);
            body.replaceText('{{City2}}', row[4]);
            body.replaceText('{{State2}}', row[5]);
            body.replaceText('{{Zip2}}', row[6]);
        }

        if (index % 4 === 3){
            body.replaceText('{{First Name3}}', row[1]);
            body.replaceText('{{Last Name3}}', row[2]);
            body.replaceText('{{Address3}}', row[3]);
            body.replaceText('{{City3}}', row[4]);
            body.replaceText('{{State3}}', row[5]);
            body.replaceText('{{Zip3}}', row[6]);
        }

        if (index % 4 === 0){
            body.replaceText('{{First Name4}}', row[1]);
            body.replaceText('{{Last Name4}}', row[2]);
            body.replaceText('{{Address4}}', row[3]);
            body.replaceText('{{City4}}', row[4]);
            body.replaceText('{{State4}}', row[5]);
            body.replaceText('{{Zip4}}', row[6]);

            // 新增:判断还有未处理数据则插入新页面和新模板
            if (index < rows.length - 1) {
                // 插入分页符
                body.appendPageBreak();
                // 追加新的模板内容,生成新的占位符组
                for (let i = 0; i < templateContent.getNumChildren(); i++) {
                    const child = templateContent.getChild(i);
                    const childType = child.getType();
                    switch(childType) {
                        case DocumentApp.ElementType.PARAGRAPH:
                            body.appendParagraph(child.asParagraph().copy());
                            break;
                        case DocumentApp.ElementType.TABLE:
                            body.appendTable(child.asTable().copy());
                            break;
                        case DocumentApp.ElementType.LIST_ITEM:
                            body.appendListItem(child.asListItem().copy());
                            break;
                        // 模板有其他元素类型可继续补充case
                    }
                }
            }
        }    
    });

    // 新增:处理最后一页不足4条数据的占位符清空
    const remainingCount = (rows.length - 1) % 4;
    if (remainingCount !== 0) {
        for (let i = remainingCount + 1; i <= 4; i++) {
            body.replaceText(`{{First Name${i}}}`, '');
            body.replaceText(`{{Last Name${i}}}`, '');
            body.replaceText(`{{Address${i}}}`, '');
            body.replaceText(`{{City${i}}}`, '');
            body.replaceText(`{{State${i}}}`, '');
            body.replaceText(`{{Zip${i}}}`, '');
        }
    }

    doc.saveAndClose();
}

注意事项

  • 如果模板包含图片、绘图等特殊元素,可对应补充switch分支的元素类型处理逻辑
  • 原始模板不要添加额外分页符,避免生成的文档分页混乱
  • 请提前测试模板内容追加逻辑,确保和原模板样式完全一致

内容的提问来源于stack exchange,提问作者TPas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 01:45:03