在 Google Docs 中操作 PositionedImage 并在图像周围环绕文本 [英] Manipulate PositionedImage and wrap text around image in Google Docs
问题描述
我使用 已修复.截至 2015 年 12 月,Google Apps 脚本可以操作
//http://stackoverflow.com/a/20661113/1677912功能 DemoPositionedImage() {//获取活动文档的句柄var doc = DocumentApp.getActiveDocument();//找到想要的图片文件var匹配文件 = DriveApp.getFilesByName('apple-touch-icon.png');if (matchedFiles.hasNext()) {//从文件中获取图像对象var image = matchingFiles.next().getBlob();//将图像添加为 PositionedImage.变量定位图像 = doc.getBody().getParagraphs()[0].addPositionedImage(image);//在这里调整布局等//记录新图像的IDLogger.log(定位图像.getId());}}
日志显示了新图像的 ID,如下所示:
[15-12-11 20:35:03:706 EST] kix.9dwnzjfapdy8
小心 - 如果您将多个图像添加到同一个元素(例如段落),使用默认布局,最新图像将覆盖现有图像.因此,实际上有一堆图像时,您可能看起来只有一张图像.
检索现有的PositionedImage
s
由于 PositionedImage
不是文档的元素,所以它不会出现在元素层次结构中,元素如段落、表格或 InlineImages,也无法通过文档方法 找到getChild()
、getNextSibling()
等等.同样,没有 Body.getPositionedImages()
与 Body.getImages()
并行.
相反,您可以使用其唯一 ID 获取 PositionedImage
,例如kix.9dwnzjfapdy8
来自前面的例子.
varlocatedImage = getPositionedImage(storedId);
或者,您可以将包含元素中的所有 PositionedImage
对象作为数组获取.
varlocatedImages = getPositionedImages();for (var i=0; i
检索文档中的所有 PositionedImage
需要遍历所有可能的锚元素.以下实用程序就是这样做的.
/*** 获取文档中所有 PositionedImages 的列表.* 参见 stackoverflow.com/a/20661113/1677912.** @param {String} docId(可选)要扫描的文档ID** @returns {PositionedImage[]} 文档中的 PositionedImages 数组*/函数 getAllPositionedImages( docId ) {//如果给定 ID,则打开文档,否则使用活动文档.如果(文档ID){var doc = DocumentApp.openById(docId);}别的 {doc = DocumentApp.getActiveDocument();}//获取文档正文的句柄var body = doc.getBody();//保存文档中所有图像的数组var allPositionedImages = [];var numElems = body.getNumChildren();for (var childIndex=0; childIndex
布局控制
PositionedImages
的大多数布局控件在文档中都有很好的描述:
- 高度:
setHeight()
,getHeight()
- 宽度:
setWidth()
,getWidth()
- LeftOffset:
setLeftOffset()
,getLeftOffset()
- TopOffset:
setTopOffset()
,getTopOffset()
- 布局:
setLayout()
,getLayout()
PositionedLayout
枚举与 Layout 方法一起使用是 PositionedImages
独有的.然而,在启动 PositionedImage 支持时,它没有包含在编辑器自动完成中,并且文档中没有包含它的使用示例.让我们填补这个空白.
您可以通过以下方法设置布局一个 PositionedImage
以便它被文本包裹:
positionedImage.setLayout( DocumentApp.PositionedLayout.WRAP_TEXT );
以下实用程序函数获取与 PositionedLayout
枚举等效的英文.
/*** 获取表示给定 PositionedLayout 枚举的字符串.* 参考:https://developers.google.com/apps-script/reference/document/positioned-layout** 参见 stackoverflow.com/a/20661113/1677912.** @param {PositionedLayout} PositionedLayout 枚举值.** @returns {String} 英文文本匹配枚举.*/函数 getLayoutString( PositionedLayout ) {无功布局;开关(定位布局){案例 DocumentApp.PositionedLayout.ABOVE_TEXT:布局 = "ABOVE_TEXT";休息;案例 DocumentApp.PositionedLayout.BREAK_BOTH:布局 = "BREAK_BOTH";休息;案例 DocumentApp.PositionedLayout.BREAK_LEFT:布局 = "BREAK_LEFT";休息;案例 DocumentApp.PositionedLayout.BREAK_RIGHT:布局 = "BREAK_RIGHT";休息;案例 DocumentApp.PositionedLayout.WRAP_TEXT:布局 = "WRAP_TEXT";休息;默认:布局=";休息;}返回布局;}
注意:这已同时发布在我的博客上.
I used the following snippet to insert an image into a Google Document:
// 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);
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 PositionedImage
s
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 PositionedImage
s 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:
- Height:
setHeight()
,getHeight()
- Width:
setWidth()
,getWidth()
- LeftOffset:
setLeftOffset()
,getLeftOffset()
- TopOffset:
setTopOffset()
,getTopOffset()
- Layout:
setLayout()
,getLayout()
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.
这篇关于在 Google Docs 中操作 PositionedImage 并在图像周围环绕文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!