操作PositionedImage并在Google文档中将图片包裹在图片周围 [英] Manipulate PositionedImage and wrap text around image in a Google Document

查看:233
本文介绍了操作PositionedImage并在Google文档中将图片包裹在图片周围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用下面的代码片段将图片插入到Google文档中:

  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);

结果是内嵌图片:



<但是,我希望有一个换行文字图片,如下所示:

这可以通过Google Apps Script(即时)吗?

解决方案

  // http://stackoverflow.com/a/20661113/1677912 
函数DemoPositionedImage(){
//获取活动文档的句柄
var doc = DocumentApp.getActiveDocument();

//找到想要的图片文件
var matchedFiles = DriveApp.getFilesByName('apple-touch-icon.png');
if(matchedFiles.hasNext()){
//从文件
获取图像对象var image = matchedFiles.next()。getBlob();

//将图像添加为PositionedImage。
var positionedImage = doc.getBody()。getParagraphs()[0] .addPositionedImage(image);

//在这里调整布局等

//记录新图像的ID
Logger.log(positionedImage.getId());
}
}

日志显示新图像的ID,这:

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

小心 - 如果您将多个图像添加到同一元素(例如段落) ,最新的图片会覆盖现有的图片。因此,实际上可能有一堆图像时,您可能看起来像是一张图像。



检索现有的 PositionedImage PositionedImage 不是文档的元素,所以它不会出现在元素层次结构中元素(如段落,表格或InlineImages),并且无法通过文档方法 getChild() getNextSibling() , 等等。同样,没有 Body.getPositionedImages()并行 Body.getImages()



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

  var positionedImage = getPositionedImage(storedId); 

或者,您可以获取所有 PositionedImage

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

检索所有 PositionedImage 在一个文档中需要遍历所有可能的锚元素。

  / ** 
*获取所有PositionedImages都放在文档中。
*请参阅stackoverflow.com/a/20661113/1677912。
*
* @param {String} docId(可选)要扫描的文档ID
*
* @returns {PositionedImage []}文档
中的PositionedImage数组* /
函数getAllPositionedImages(docId){
//如果给定ID,则打开文档,否则使用活动文档。
if(docId){
var doc = DocumentApp.openById(docId);
}
else {
doc = DocumentApp.getActiveDocument();
}

//获取文档正文的句柄
var body = doc.getBody();

//数组保存文档
中的所有图像var allPositionedImages = [];

var numElems = body.getNumChildren(); (var childIndex = 0; childIndex< numElems; childIndex ++){
var $ child = body.getChild(childIndex);


switch(child.getType()){
case DocumentApp.ElementType.PARAGRAPH:
var container = child.asParagraph();
休息;
case DocumentApp.ElementType.LIST_ITEM:
container = child.asListItem();
休息;

默认值:
//跳过不能包含PositionedImages的元素。
继续;
}
//从当前容器收集图像
var imagesHere = container.getPositionedImages();
allPositionedImages = allPositionedImages.concat(imagesHere);
}
返回allPositionedImages;



$ b $ h $布局控制

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



Layout 方法一起使用的 c> PositionedLayout enum 对于<$ c是独一无二的$ C> PositionedImages 。但是,在支持PositionedImage的时候,它并未包含在编辑器自动完成中,而且文档中没有包含它的使用示例。让我们填补这一空白。



以下是您可以如何设置 PositionedImage 的布局,以便用文本包装:

 定位图像.setLayout(DocumentApp.PositionedLayout.WRAP_TEXT); 

以下效用函数的英文等同于 PositionedLayout enum。

/ **
*获取表示给定的字符串PositionedLayout枚举。
*参考:https://developers.google.com/apps-script/reference/document/positioned-layout
*
*请参阅stackoverflow.com/a/20661113/1677912。
*
* @param {PositionedLayout} PositionedLayout枚举值。
*
* @returns {String}与enum匹配的英文文本。
* /
函数getLayoutString(PositionedLayout){
var layout;
switch(PositionedLayout){
case DocumentApp.PositionedLayout.ABOVE_TEXT:
layout =ABOVE_TEXT;
休息;
案例DocumentApp.PositionedLayout.BREAK_BOTH:
layout =BREAK_BOTH;
休息;
案例DocumentApp.PositionedLayout.BREAK_LEFT:
layout =BREAK_LEFT;
休息;
案例DocumentApp.PositionedLayout.BREAK_RIGHT:
layout =BREAK_RIGHT;
休息;
案例DocumentApp.PositionedLayout.WRAP_TEXT:
layout =WRAP_TEXT;
休息;
默认值:
layout =;
休息;
}
返回布局;
}

注意:已同时发布在我的博客上。


I used the following snippet to insert an image into a Google Document:

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);

The result is an In line image:

I want, however, to have a Wrap text image, like so:

Is that possible via Google Apps Script (on the fly)?

解决方案

Issue 1529 has been fixed. As of December 2015, Google Apps Script can manipulate PositionedImage objects in Google Docs.


They behave a little differently than InlineImage elements, as they need to be anchored to a ListItem or Paragraph element, while InlineImages can be added only to Body, FooterSection, HeaderSection or TableCell elements.

A PositionedImage is an object anchored in an element, while an InlineImage is itself an element of a document. This implies that you cannot convert one type of image directly to the other. (When you switch an image from "Wrap text" to "Inline" using the UI, the PositionedImage is removed from its anchor paragraph, then inserted into the body of the document outside of that paragraph. You could emulate that via script if necessary.)

Insert a PositionedImage

Here's an example of a PositionedImage inserted by the following script:

// 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() );
  }
}

The log shows the ID of the new image, like this:

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

Be careful - if you add multiple images to the same element (e.g. Paragraph), with default layout, the newest image will overlay existing ones. Therefore, it may look like you have a single image when there are actually a pile of them.

Retrieve existing PositionedImages

Since a PositionedImage is not an element of a document, it does not appear in the element hierarchy with elements like paragraphs, tables, or InlineImages, and cannot be found through the document methods getChild(), getNextSibling(), and so on. Likewise, there is no Body.getPositionedImages() to parallel Body.getImages().

Instead, you can get a PositionedImage using its unique ID, e.g. kix.9dwnzjfapdy8 from the earlier example.

var positionedImage = getPositionedImage(storedId);

Alternatively, you can get all the PositionedImage objects in a containing element as an array.

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

Retrieving all the PositionedImages in a document requires traversing all the possible anchor elements. The following utility does just that.

/**
 * 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;
}

Layout control

Most of the layout controls for PositionedImages are well described in the documentation:

The PositionedLayout enum used with the Layout methods is unique to PositionedImages. At the time of launch of PositionedImage support however, it was not included in editor autocompletion, and the documentation contained no examples of its use. Let's fill that gap.

Here's how you can set the layout of a PositionedImage so that it is wrapped by text:

positionedImage.setLayout( DocumentApp.PositionedLayout.WRAP_TEXT );

The following utility function gets the English equivalent of a PositionedLayout enum.

/**
 * 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;
}

Note: This has been concurrently posted on my blog.

这篇关于操作PositionedImage并在Google文档中将图片包裹在图片周围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆