如何使用Google脚本(以编程方式)将图像从一个表格单元格复制到google文档中的另一表格单元格中?

时间:2018-12-20 18:04:06

标签: google-apps-script google-docs google-docs-api

我想将一个Google文档的内容复制到另一个。内容包括文本,表格和图像。

我的代码复制文本和表格。但是,表单元格中包含的所有内容都不会被复制。

我在以下位置提供了代码的简化版本和单个文档:https://docs.google.com/document/d/1hcQzBuMA6E15u8VtW2lWGL7XCcU3qVsDhn-5jiznQP4/edit?usp=sharing

该代码只是复制粘贴Google文档的内容,该文档包括一个包含表/图像的表。发生相同的问题。单元格的内容不会被复制。 see screenshot

这是代码的简化版:

function test() {
  
  // Make Copy of template file
  doc = DocumentApp.getActiveDocument();
  body =doc.getBody();
  

  
  /// Copy elements from source file to target file one bich one
  var totalElements = body.getNumChildren();
  var types = new Array;
  
  for( var iel = 0; iel < totalElements; iel++ ) {
     current_body = doc.getBody();
    var element = body.getChild(iel).copy();
    var type = element.getType();
    types.push(type);
    
    switch(type){
      case DocumentApp.ElementType.PARAGRAPH:
        body.appendParagraph(element);
        break;
      case DocumentApp.ElementType.TABLE:
        var newTable =body.insertTable( body.getNumChildren()-1, element );
        CopyTableCellByCell( element, newTable );
        break;
      case DocumentApp.ElementType.LIST_ITEM:
        body.appendListItem(element);
        break;
      case DocumentApp.ElementType.INLINE_IMAGE:
        body.appendImage(element); 
        break;
        
    }
  }
  doc.saveAndClose();
}

// recursive function that replaces each cell by first clearing it and Copying the content from the original table
function CopyTableCellByCell( srcTable, dstTable ) {
  var numRows = srcTable.getNumRows();
  var srcRow, numCells, dstCell, icell;
  var types = new Array;
  
  for ( var irow = 0; irow < numRows; irow++ ) {// EACH ROW
    srcRow = srcTable.getRow( irow );
    dstRow = dstTable.getRow( irow );
    numCells = srcRow.getNumCells();
    
    for ( icell = 0; icell < numCells; icell++ ) { // EACH CELL
      dstCell = dstRow.getCell( icell );
      dstCell.clear();
      var srcCell = srcTable.getCell( irow, icell );
      var numCellChildren = srcCell.getNumChildren(); // ==> outputs 1 paragraph child instead of a paragraph and a table.
      
      
      for ( var ich = 0; ich < numCellChildren; ich++ ) { // EACH CHILD
        var cellChild = srcCell.getChild( ich );
        var childCopy = cellChild.copy();
        var type = childCopy.getType();
        types.push(type);


        switch( type ){
            
          case DocumentApp.ElementType.PARAGRAPH:
            dstCell.insertParagraph( ich, childCopy );
            break;
            
          case DocumentApp.ElementType.LIST_ITEM:
            var atts    = childCopy.getAttributes();
            var newListItem = dstCell.insertListItem( ich, childCopy );
            newListItem.setAttributes( atts );
            break;
            
          case DocumentApp.ElementType.TABLE:

            var newTable = dstCell.insertTable( ich, childCopy );
            CopyTableCellByCell( cellChild, newTable );
            break;
            
          case DocumentApp.ElementType.INLINE_IMAGE:
            var parpar = childCopy.getParent();
            var ttt = parpar.getType();
            destImg = parpar.insertInlineImage(l, childCopy.getBlob()); 
            dstImg.setWidth(childCopy.getWidth());
            dstImg.setHeight(childCopy.getHeight());
            break;

        }
        
      }

    }
  }
}

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

此修改如何?我和你也经历过同样的情况。当时,我使用了这种解决方法。我认为您的情况可能有几种解决方案。因此,请将此视为其中之一。

修改点:

  • 如果复制表,则在包含图像的单元格时,它将图像从源表复制到目标表。由此,可以看到图像。流程如下。
    1. 将源表复制到目标表。
    2. 检索单元格中的段落。
    3. 检索图像。
    4. 从目标单元格中​​删除图像。
    5. 将图像从源单元格复制到目标单元格。

修改后的脚本:

请进行如下修改。

从:
else if( type == DocumentApp.ElementType.TABLE){
  body.appendTable(element);
}
至:
else if( type == DocumentApp.ElementType.TABLE){
  var dstTable = body.appendTable(element);
  var srcTable = element.asTable();
  var row = srcTable.getNumRows();
  for (var i = 0; i < row; i++) {
    var col = srcTable.getRow(i).getNumCells();
    for (var j = 0; j < col; j++) {
      var cell = srcTable.getCell(i, j);
      var c1 = cell.getNumChildren();
      for (var k = 0; k < c1; k++) {
        var paragraph = cell.getChild(k).asParagraph();
        var c2 = paragraph.getNumChildren();
        for (var l = 0; l < c2; l++) {
          var child = paragraph.getChild(l);
          var t = child.getType();
          if (t === DocumentApp.ElementType.INLINE_IMAGE) {
            var srcImg = child.asInlineImage();
            var dstParagraph = dstTable.getCell(i, j).getChild(k).asParagraph().clear();
            var dstImg = dstParagraph.insertInlineImage(l, srcImg.getBlob());
            dstImg.setWidth(srcImg.getWidth());
            dstImg.setHeight(srcImg.getHeight());
          }
        }
      }
    }
  }
}

参考文献:

尽管在我的环境中,我可以确认将问题中的图像用作示例情况时,此修改后的脚本可以工作,但如果在您的环境中不可行,我很抱歉。

编辑1:

对于您添加的情况,请按如下所示修改脚本。

发件人:

else if( type == DocumentApp.ElementType.TABLE){
  body.appendTable(element);
}

收件人:

else if( type == DocumentApp.ElementType.TABLE){
  var dstTable = body.appendTable(element);
  var srcTable = element.asTable();
  copyTable(srcTable, dstTable);
}

请添加以下功能。

function copyTable(srcTable, dstTable) {
  var row = srcTable.getNumRows();
  for (var i = 0; i < row; i++) {
    var col = srcTable.getRow(i).getNumCells();
    for (var j = 0; j < col; j++) {
      var cell = srcTable.getCell(i, j);
      var c1 = cell.getNumChildren();
      for (var k = 0; k < c1; k++) {
        var ty = cell.getChild(k).getType();
        if (ty === DocumentApp.ElementType.TABLE) {
          srcTable = cell.getChild(k).asTable();
          dstTable = dstTable.getCell(i, j).getChild(k).asTable();
          return copyTable(srcTable, dstTable);
        } else {
          var paragraph = cell.getChild(k).asParagraph();
          var c2 = paragraph.getNumChildren();
          for (var l = 0; l < c2; l++) {
            var child = paragraph.getChild(l);
            var t = child.getType();
            if (t === DocumentApp.ElementType.INLINE_IMAGE) {
              var srcImg = child.asInlineImage();
              var dstParagraph = dstTable.getCell(i, j).getChild(k).asParagraph().clear();
              var dstImg = dstParagraph.insertInlineImage(l, srcImg.getBlob());
              dstImg.setWidth(srcImg.getWidth());
              dstImg.setHeight(srcImg.getHeight());
            }
          }
        }
      }
    }
  }
}

编辑2:

对于您添加的情况,请按如下所示修改脚本。

发件人:

else if( type == DocumentApp.ElementType.TABLE){
  body.appendTable(element);
}

收件人:

else if( type == DocumentApp.ElementType.TABLE){
  var dstTable = body.appendTable(element);
  var srcTable = element.asTable();
  copyTable(srcTable, dstTable);
}

请添加以下功能。

function copyTable(srcTable, dstTable) {
  var row = srcTable.getNumRows();
  for (var i = 0; i < row; i++) {
    var col = srcTable.getRow(i).getNumCells();
    for (var j = 0; j < col; j++) {
      var cell = srcTable.getCell(i, j);
      var c1 = cell.getNumChildren();
      for (var k = 0; k < c1; k++) {
        var ty = cell.getChild(k).getType();
        if (ty === DocumentApp.ElementType.TABLE) {
          srcTable = cell.getChild(k).asTable();
          dstTable = dstTable.getCell(i, j).getChild(k).asTable();
          return copyTable(srcTable, dstTable);
        } else {
          var paragraph = cell.getChild(k).asParagraph();
          var c2 = paragraph.getNumChildren();
          for (var l = 0; l < c2; l++) {
            var child = paragraph.getChild(l);
            var t = child.getType();
            if (t === DocumentApp.ElementType.INLINE_IMAGE) {
              var srcImg = child.asInlineImage();
              var dstParagraph = dstTable.getCell(i, j).getChild(k).asParagraph();
              dstParagraph.getChild(l).asInlineImage().removeFromParent();
              var dstImg = dstParagraph.insertInlineImage(l, srcImg.getBlob());
              dstImg.setWidth(srcImg.getWidth());
              dstImg.setHeight(srcImg.getHeight());
            }
          }
        }
      }
    }
  }
}

答案 1 :(得分:0)

该代码几乎可以正常运行。最后一个问题是与图像对齐的文本不会被复制。

我现在使用其他功能重组了代码。 copyContent()调用copyTable()调用copyCellChild()

copyCellChild(),将单元格的子级从源单元格复制到目标单元格的函数会导致错误。

copyCellChild()忽略与图像一致的文本。

function copyContent() {
  
  // Make Copy of template file
  doc = DocumentApp.getActiveDocument();
  body =doc.getBody();
  
  
  /// Copy elements from source file to target file one bich one
  var totalElements = body.getNumChildren();
  var types = new Array;
  
  for( var iel = 0; iel < totalElements; iel++ ) {
    current_body = doc.getBody();
    var element = body.getChild(iel).copy();
    var type = element.getType();
    types.push(type);
    
    switch(type){
      case DocumentApp.ElementType.PARAGRAPH:
        body.appendParagraph(element);
        break;
      case DocumentApp.ElementType.TABLE:
        //var newTable =body.insertTable( body.getNumChildren()-1, element );
        //CopyTableCellByCell( element, newTable );
        var dstTable = body.appendTable(element);
        var srcTable = element.asTable();
        copyTable(srcTable, dstTable);
        break;
      case DocumentApp.ElementType.LIST_ITEM:
        body.appendListItem(element);
        break;
      case DocumentApp.ElementType.INLINE_IMAGE:
        body.appendImage(element); 
        break;
        
    }
  }
  doc.saveAndClose();
}

function copyTable(srcTable, dstTable) {
  
  var row = srcTable.getNumRows();
  
  for (var i = 0; i < row; i++) { // ROW
    var col = srcTable.getRow(i).getNumCells();
    
    for (var j = 0; j < col; j++) { // CELL
      
      var srcCell = srcTable.getCell(i, j);
      var c1 = srcCell.getNumChildren();
      var destCell = dstTable.getCell(i, j);
      
      for (var k = 0; k < c1; k++) { // CHILD
        copyCellChild(srcCell,destCell,k);        
      }
    }
  }
}


function copyCellChild(srcCell,destCell,k){
  
  var srcChild = srcCell.getChild(k);
  var destChild = destCell.getChild(k);
  var ty = srcChild.getType();
  
  switch(ty){
      
    case DocumentApp.ElementType.TABLE:
      srcTable = srcChild.asTable();
      dstTable = destChild.asTable();
      return copyTable(srcTable, dstTable);
      break;
      
    case DocumentApp.ElementType.INLINE_IMAGE:
      var srcImg = srcChild.asInlineImage();
      var dstParagraph = destChild.asParagraph();
      
      
      var dstImg = dstParagraph.insertInlineImage(l, srcImg.getBlob());
      dstImg.setWidth(srcImg.getWidth());
      dstImg.setHeight(srcImg.getHeight());
      break;
      
    case DocumentApp.ElementType.PARAGRAPH:
      var paragraph = srcChild.asParagraph();//
      var c2 = paragraph.getNumChildren();
      
      
      for (var l = 0; l < c2; l++) { // PARAGRAPH CHILDREN

        try{
          var srcParaChild = paragraph.getChild(l);
          var t = srcParaChild.getType();
          
          switch(t){
              
            case DocumentApp.ElementType.INLINE_IMAGE:
              
              var srcImg = srcParaChild.asInlineImage();
              var dstParagraph = destChild.asParagraph().clear();
              //var dstParagraph = destChild.asInlineImage().clear();//clear
              
              var dstImg = dstParagraph.insertInlineImage(l, srcImg.getBlob());
              dstImg.setWidth(srcImg.getWidth());
              dstImg.setHeight(srcImg.getHeight());
              dstImg.setLinkUrl(srcImg.getLinkUrl);
              break;
            case DocumentApp.ElementType.TEXT:
              //var srcTxt = srcChild.getText();
              //Logger.log(srcTxt);
              //var iii = 1;
              //destChild.asText().appendText(srcTxt);
              
          }
        }catch(e){// text in line with images
          var srcTxt = srcChild.getText();
          Logger.log(srcTxt);
          var iii = 1;
          destChild.asText().appendText(srcTxt);
          
        }
      }
  }
  
}

以下是示例Google文档,您可以在其中运行以下功能:https://docs.google.com/document/d/1hcQzBuMA6E15u8VtW2lWGL7XCcU3qVsDhn-5jiznQP4/edit#