我使用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
图片:
但是,我希望拥有Wrap text
图像,如下所示:
这可以通过Google Apps脚本(动态)吗?
答案 0 :(得分:11)
Issue 1529已修复。截至2015年12月,Google Apps脚本可以操纵Google文档中的PositionedImage
个对象。
它们的行为与InlineImage
元素略有不同,因为它们需要锚定到ListItem或Paragraph元素,而InlineImages
只能添加到Body
,FooterSection
},HeaderSection
或TableCell
元素。
PositionedImage
是锚定在元素中的对象,而InlineImage
本身是文档的元素。 这意味着您无法将一种类型的图像直接转换为另一种图像。(当您使用UI将图像从“自动换行”切换为“内联”时,PositionedImage
将从它的锚段,然后插入该段之外的文档正文。如果需要,你可以通过脚本模拟它。)
PositionedImage
以下是由以下脚本插入的PositionedImage
示例:
// 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
的大多数布局控件都在文档中有详细描述:
setHeight()
,getHeight()
setWidth()
,getWidth()
setLeftOffset()
,getLeftOffset()
setTopOffset()
,getTopOffset()
setLayout()
,getLayout()
布局方法使用的PositionedLayout
enum对PositionedImages
是唯一的。但是,在启动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。