I'm developing a PowerPoint add-in with the feature to upload a presentation to the web server. I have a presentation with 100MB exact size. I used the guidelines for using GetFileAsync in Office docs. It is working for small presentation files. But the add-in message of not responding when I select largely presentation file. I did break point to the code and I found out that the cause of not responding is in js due to the large array slices. There is no problem with getting the slices of a large file. But the problem in when slices array concat to be one array.
Here's the code came from Office docs where the issue occurred.
function onGotAllSlices(docdataSlices) {
var docdata = [];
for (var i = 0; i < docdataSlices.length; i++) {
docdata = docdata.concat(docdataSlices[i]);
}
var fileContent = new String();
for (var j = 0; j < docdata.length; j++) {
fileContent += String.fromCharCode(docdata[j]);
}
// Now all the file content is stored in 'fileContent' variable,
// you can do something with it, such as print, fax...
}
I don't know if it is a bug or issue on the part of Office Add-in. I hope someone helps me.
Thanks in advance.
UPDATES:
I simplify the given function like this:
function onGotAllSlices(docdataSlices) {
var fileContent = new String();
for(var i = 0; i < docdataSlices.length; i++) {
var docdata = docdataSlides[i];
for(var j = 0; j < docdata.length; j++) {
fileContent += String.fromCharCode(docdata[j]);
}
}
var base64String = window.btoa(fileContent);
}
So far, there is no 'out of memory' issue at all. But there is another issue with error message of '8007000e. “Not enough storage is available to complete this operation”' when the fileContent convert in base64String.
This looks like it's a performance problem. Have you checked How to extend an existing JavaScript array with another array, without creating a new array? ? .concat will create a new array from the previous two ones, which you're re-assigning. Perhaps there's a better way of doing this?
Related
I need to transfer ownership of thousands of files I own to someone else with editing access, but I've learned that Google Drive requires you to do this one file at a time. With intermediate but growing JS experience I decided to write a script to change the owner from a list of file IDs in a spreadsheet, however I've run into trouble and I have no idea why. The debugger just runs through the script and everything looks sound for me. I'd greatly appreciate any help.
function changeOwner() {
var ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/********/').getSheetByName('Sheet1');
var range = ss.getRange(1,1,2211);
for (i = 0; i < range.length; i++){
var file = range[i][0].getValue();
var fileid = DriveApp.getFileById(file);
fileid.setOwner('******#gmail.com');
}
}
Tested below code working fine with IDs,
function myFunction() {
var spreadsheet = SpreadsheetApp.openById('ID');
var range = spreadsheet.getDataRange().getValues();
for (i = 0; i < range.length; i++){
var file = range[i][0].toString();
var fileid = DriveApp.getFileById(file);
fileid.setOwner('***#gmail.com');
}
}
Your issue is that the Range class had no length property. Instead, perform a getValues() call on the range to efficiently create a JavaScript array, and iterate on it:
function changeOwner() {
var ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/********/').getSheetByName('Sheet1');
var values = ss.getRange(1, 1, 2211).getValues();
for (i = 0; i < values.length; ++i){
var fileid = value[i][0];
var file = DriveApp.getFileById(fileid);
file.setOwner('******#gmail.com');
}
}
There are other improvements you can make, such as:
dynamic range read (rather than the fixed assumption of 2211 rows of data)
writing to a second array to keep track of which files you have yet to process
checks for if the file exists
checks for if the file is actually owned by you
checks for execution time remaining, to allow serializing any updates/tracking you do that prevents the next execution from repeating what you just did
and so on. I'll let you research those topics, and the methods available in Apps Script documentation for the DriveApp, SpreadsheetApp, Sheet, and Range classes. Note that you also have all features of Javascript 1.6 available, so many of the things you find on a Javascript Developer Reference (like MDN) are also available to you.
I've currently butchered a script I was reading that loops through a list of layers, and then looks for layers with a certain name (3/2, 4/3 etc). The next step is to check for layer masks that are clipped to the base layer, and merge them to it. I've read through the reference docs, and can't find anything about identifying clipping masks. I've attached an image as an example of how the document is structured.
And here is the code I have so far:
var doc = app.activeDocument
var ratios = ["1/1", "4/3", "3/4", "3/2", "2/3", "16/9", "9/3", "7/2", "11/5"];
for (var i = 0, il = doc.layers.length; i < il; i++) {
var curLayer = doc.layers[i];
for (var j = 0, jl = ratios.length; j < jl; j++) {
if (curLayer.name == ratios[j]) {
alert(curLayer.name);
// Check for clipping masks attached to this layer
}
}
}
I am using Photoshop CS5. Thanks!
I ended up working out another way to do it. I instead grouped the layers into a layerset, and exported them out of the document that way. For those that would like to see it, have a look here:
https://gist.github.com/BeauAgst/4da366b933cc75a0606a
I've seen a few posts on extracting images from PDF using iTextSharp, but all are VB/C# based.
A core part of these solutions is something like:
PdfDictionary res = (PdfDictionary)(PdfReader.GetPdfObject(dict.Get(PdfName.RESOURCES)));
PdfDictionary xobj = (PdfDictionary)(PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT)));
if (xobj != null)
{
foreach (PdfName name in xobj.Keys)
I can create the res and xobj objects fine in Jscript, but JScript does not support foreach loops. I have to do something like
for
(var x = 0; x < xobj.Keys.Count; x++)
{
var name = xobj.Keys(x)
...
}
But this is of course invalid.
Can someone explain how I can parse all the keys in xobj, without using foreach loops?
I'm studying Java so I'm pretty new.
I'm creating a simple 'maze' type game using GUI layouts, images, labels ect..
To create my maze layouts I used an array of strings;
mazeLayout[0] = "WWWWWWWWWW";
mazeLayout[1] = "WSSSWWSWWW";
mazeLayout[2] = "WSWSWWSSSW";
mazeLayout[3] = "WSWSWWWWSW";
mazeLayout[4] = "WSWSWWWWSW";
mazeLayout[5] = "WSWSWSSSSW";
mazeLayout[6] = "WSWSWSWWWW";
mazeLayout[7] = "WSWSWSWWWW";
mazeLayout[8] = "WSWSSSWWWW";
mazeLayout[9] = "WWWWWWWWWW";
and then converted this into a 2d array and placed a label with in image icon in it depending on the string being 'W' for wall or 'S' for space. Also the labels are an array, my thoughts behind this was for restricting movement of the player so they can't walk though walls.
int mw = 0;
int mf = 0;
for(int y = 0; y < 10; y++){
for(int x = 0; x < 10; x++){
mazeLayout2d[y][x] = mazeLayout[y].substring(x, x+1);
if (mazeLayout2d[y][x].equals("W")){
lblmazewall[mw] = new JLabel();
mazewall = new ImageIcon("mazewall.png");
lblmazewall[mw].setIcon(mazewall);
pCenter.add(lblmazewall[mw]);
mw++;
pCenter.revalidate();
}
if (mazeLayout2d[y][x].equals("S")){
lblmazefloor[mf] = new JLabel();
mazefloor = new ImageIcon("mazefloor.png");
lblmazefloor[mf].setIcon(mazefloor);
pCenter.add(lblmazefloor[mf]);
mf++;
pCenter.revalidate();
}
}
}
My problem is when i run this line
System.out.println(lblmazewall[x].getLocation()); //x being any number
I always get java.awt.Point[x=0,y=0]
I would like to know how to get the location of each wall label so i can check it against my player movement.
Is this even a valid way to do something like this?
Could someone teach me a more efficient way?
Sorry for my crude snippets and or bad programming
Thankyou Niall.
public Point getLocation()
Due to the asynchronous nature of native event handling, this method can return outdated values (for instance, after several calls of setLocation() in rapid succession). For this reason, the recommended method of obtaining a component's position is within java.awt.event.ComponentListener.componentMoved(), which is called after the operating system has finished moving the component.
The layout might not have used setLocation() internally. So that getLocation() does not return the value as expected.
I'm trying to make a script that will resize the images in a google doc. What I have is:
var imgs = currentDoc.getImages();
for (var i = 1; i < imgs.length; i++)
{
cell = row.insertTableCell(1);
imgNew = imgs[i].setWidth(365);
cell.insertImage(1, imgNew.getBlob());
}
The image gets inserted correctly but the size does not change regardless of what I set the width to. Since the image is going into a cell (width=370), is it possible to just make the image take up 100% of the width and scale the height proportionally? If not I can deal with manually setting the number of pixels but that is not working either. Any ideas?
The problem is that the image size should be changed after it is inserted to a table. The following code works correctly
function test() {
var doc = DocumentApp.openById('here_is_doc_id');
var imgs = doc.getImages();
var table = doc.getTables()[0];
for (var i = 0; i < imgs.length; i++) {
var row = table.appendTableRow();
var cell = row.insertTableCell(0);
var imgNew = imgs[i].copy();
cell.insertImage(0, imgNew);
imgNew.setWidth(365);
}
}
Please mention, that array indexes, cells numbers, etc. start from 0 and not 1.
Just as an FYI, you don't need to call getBlob()... anything that has a getBlob() can be passed in directly wherever a Blob is needed.
Have you tried:
imgs[i].attr('width', '370');
Or try assigning a class that has width: 100%