在Google文档中处理PositionedImage并在图像周围包装文本

时间:2013-11-28 20:30:07

标签: google-apps-script google-docs

我使用following snippet将图片插入Google文档:

// Source: http://stackoverflow.com/a/18859986/1536038
var doc = DocumentApp.openById('Google Drive Id');
var img = DriveApp.getFileById('Google Drive Id').getBlob(); 
doc.getBody().insertImage(0, img);

结果是In line图片:
enter image description here

但是,我希望拥有Wrap text图像,如下所示: enter image description here

这可以通过Google Apps脚本(动态)吗?

1 个答案:

答案 0 :(得分:11)

Issue 1529已修复。截至2015年12月,Google Apps脚本可以操纵Google文档中的PositionedImage个对象。


它们的行为与InlineImage元素略有不同,因为它们需要锚定到ListItem或Paragraph元素,而InlineImages只能添加到BodyFooterSection },HeaderSectionTableCell元素。

PositionedImage是锚定在元素中的对象,而InlineImage本身是文档的元素。 这意味着您无法将一种类型的图像直接转换为另一种图像。(当您使用UI将图像从“自动换行”切换为“内联”时,PositionedImage将从它的锚段,然后插入该段之外的文档正文。如果需要,你可以通过脚本模拟它。)

插入PositionedImage

以下是由以下脚本插入的PositionedImage示例:

Screenshot

// http://stackoverflow.com/a/20661113/1677912
function DemoPositionedImage() {
  // Get handle on active document
  var doc = DocumentApp.getActiveDocument();

  // Find desired image file
  var matchedFiles = DriveApp.getFilesByName('apple-touch-icon.png');
  if (matchedFiles.hasNext()) {
    // Get image object from file
    var image = matchedFiles.next().getBlob(); 

    // Add image as a PositionedImage.
    var positionedImage = doc.getBody().getParagraphs()[0].addPositionedImage(image);

    // Adjust layout, etc. here

    // Log the ID of the new image
    Logger.log( positionedImage.getId() );
  }
}

日志显示新图像的ID,如下所示:

[15-12-11 20:35:03:706 EST] kix.9dwnzjfapdy8

注意 - 如果您将多个图像添加到同一元素(例如段落),使用默认布局,最新图像将覆盖现有图像。因此,当实际存在一堆图像时,它可能看起来像是一张图像。

检索现有的PositionedImage s

由于PositionedImage不是文档的元素,因此它不会出现在包含段落,表格或内联图像等元素的元素层次结构中,并且无法通过文档方法getChild()找到, getNextSibling(),等等。同样,没有Body.getPositionedImages()并行Body.getImages()

相反,您可以使用其唯一ID获取PositionedImage,例如来自前面示例的kix.9dwnzjfapdy8

var positionedImage = getPositionedImage(storedId);

或者,您可以将包含元素中的所有PositionedImage个对象作为数组。

var positionedImages = getPositionedImages();
for (var i=0; i<positionedImages.length; i++) {
  Logger.log( positionedImages[i].getId() );
}

检索文档中的所有PositionedImage需要遍历所有可能的锚元素。以下实用程序就是这样做的。

/**
 * Get a list of all PositionedImages in a document.
 * See stackoverflow.com/a/20661113/1677912.
 *
 * @param {String} docId         (optional) ID of document to scan
 *
 * @returns {PositionedImage[]}  Array of PositionedImages in document
 */
function getAllPositionedImages( docId ) {
  // Open document if given ID, otherwise use active document.
  if (docId) {
    var doc = DocumentApp.openById(docId);
  }
  else {
    doc = DocumentApp.getActiveDocument();
  }

  // Get handle on document's body
  var body = doc.getBody();

  // array to hold all images in document
  var allPositionedImages = [];

  var numElems = body.getNumChildren();

  for (var childIndex=0; childIndex<numElems; childIndex++) {
    var child = body.getChild(childIndex);
    switch ( child.getType() ) {
      case DocumentApp.ElementType.PARAGRAPH:
        var container = child.asParagraph();
        break;
      case DocumentApp.ElementType.LIST_ITEM:
        container = child.asListItem();
        break;

      default:
        // Skip elements that can't contain PositionedImages.
        continue;
    }
    // Collect images from current container
    var imagesHere = container.getPositionedImages();
    allPositionedImages = allPositionedImages.concat(imagesHere);        
  }
  return allPositionedImages;
}

布局控制

PositionedImages的大多数布局控件都在文档中有详细描述:

布局方法使用的PositionedLayout enumPositionedImages是唯一的。但是,在启动PositionedImage支持时,它没有包含在编辑器自动完成中,并且文档中没有包含其使用示例。让我们填补这个空白。

以下是您PositionedImage set the layout的方式,以便它被文字包裹:

positionedImage.setLayout( DocumentApp.PositionedLayout.WRAP_TEXT );

以下效用函数的英语等效于PositionedLayout枚举。

/**
 * Get the string representing the given PositionedLayout enum.
 * Ref: https://developers.google.com/apps-script/reference/document/positioned-layout
 *
 * See stackoverflow.com/a/20661113/1677912.
 *
 * @param {PositionedLayout} PositionedLayout  Enum value.
 *
 * @returns {String}         English text matching enum.
 */
function getLayoutString( PositionedLayout ) {
  var layout;
  switch ( PositionedLayout ) {
    case DocumentApp.PositionedLayout.ABOVE_TEXT:
      layout = "ABOVE_TEXT";
      break;
    case DocumentApp.PositionedLayout.BREAK_BOTH:
      layout = "BREAK_BOTH";
      break;
    case DocumentApp.PositionedLayout.BREAK_LEFT:
      layout = "BREAK_LEFT";
      break;
    case DocumentApp.PositionedLayout.BREAK_RIGHT:
      layout = "BREAK_RIGHT";
      break;
    case DocumentApp.PositionedLayout.WRAP_TEXT:
      layout = "WRAP_TEXT";
      break;
    default:
      layout = "";
      break;
  }
  return layout;
}

注意:已同时发布on my blog