Empty image when inserting inlineimage in Document - google-apps-script

I have a spreadsheet containing a chart, and I would like to add this chart as an image to a google Doc.
Everything seems to be going fine, but the image does not contain any visuals, it is just an empty shell. The size of it seems ok, I know this because I did a manual copy paste of the chart from the spreadsheet to the document and the size of the resulting image is the same.
The code I use is as follow:
var body = DocumentApp.openById(docId).getBody();
var start_offset = body.findText("##_CHART_01").getStartOffset();
var chart = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("charts").getCharts()[0].getAs("image/png");
body.findText("##_CHART_01").getElement().getParent().asParagraph().insertInlineImage(start_offset, chart);
I have no idea why the image is empty, although it takes the space as if the image was there.
If anyone know, please enlighten me
Regards
Crouz

Related

Creating a Scatter Graph using Scripting for Google Sheets?

Google sheet and script: https://docs.google.com/spreadsheets/d/1Vq2MYQzbaRoYg31IRkwNOofJYYOH82ElSdN7miExiVQ/edit?usp=sharing
I currently am trying to create a scatter graph using data that I have been given but only using script, so I am making this scatter graph based on the data in B15 tp W16 but this data is placed in these cells by using the new applied menubar option called "Apply Script".
So if you click:
Apply Script > Activate Script
This will change the cell sizes, change the font size, create a conditional format for the data within cells C3 to W13, and will create a key for the data as well.
Then if you click:
Apply Script > Select Power Input > Select any option
Once you select which row of data you want to view, it'll be applied with cells B15 to W16 (It will make more sense if you try it yourself).
These functions will be applied to any given data that is active, I have 3 sheets within the document below so it demonstrates this.
So now that I have explained how my scripting works so far, I want to know how to script a scatter graph using any given data that is cell B15 to W16. Everything I have demonstrated above is all that I have taught myself in the past 3 days watching videos but I can't find any demonstrations for creating a chart on google scripting anywhere, I have also searched through script.google.com to find the coding needed but I couldn't understand where to start and how to present it. So if anyone can point me in the right direction that'll be great, thank you!
https://docs.google.com/spreadsheets/d/1Vq2MYQzbaRoYg31IRkwNOofJYYOH82ElSdN7miExiVQ/edit?usp=sharing
This is my existing chart script:
function lineGraph() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var row = sheet.getRange( 15, 2, 2, 22).getValues();
sheet.newChart().addRange().asScatterChart().getChartType().SCATTER;
}
Your script is certainly in the right direction, but you have to specify where to place your chart in the sheet by using setPosition.
Also, I added some options for the generated chart to make more sense based on your input.
Sample Code:
function lineGraph() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var row = sheet.getRange("B15:W16");
var chart = sheet.newChart()
.asScatterChart()
.addRange(row)
.setPosition(18,2,0,0)
.setTransposeRowsAndColumns(true)
.build();
sheet.insertChart(chart);
}
Sample Output:
Note that this is bare bones, you can specify more options by adding more methods onto the chartBuilder. Please see reference here:
Embedded Scatter Chart Builder

How to get an "image in cell" from a spreadsheet and copy it into a document as INLINE_IMAGE?

I've set-up a spreadsheet as a DB to store catalog-like information. An important element of this information is an image the end user inserts in a user-front sheet using the Google Spreadsheet's menu option "Insert --> Image --> Image in cell". This image is then copied into the storage sheet using "SpreadsheetApp.CopyPasteType.PASTE_VALUES" in a script.
Now I'm crafting a document as an output of the information stored in the DB. The issue is that I can't parse the image from the spreadsheet to the document. I'm not even being able to get it from the spreadsheet.
I've surfed the web for a solution but got nothing. The closest I found is a 2 year-old similar question without a direct response: how to copy IMAGE from a google spreadsheet to a google document in script?
My logic says that if I pasted the image-in-cell as a value, I should be able to get it back with .getValue() but obviously is not the case. I've tried to get it as a blob with no luck. I'm not too familiar with blobs so probably I did it wrong.
Any idea will be much appreciated :)
// This is the code I used to put the image in the cell (THIS WORKS, JUST FOR CONTEXT)
var fotosToCopy = cotizador.getRangeByName('CotizacionFotos');
fotosToCopy.copyTo(destino.getRange(fila,2),
SpreadsheetApp.CopyPasteType.PASTE_VALUES, true);
// This is the code I'm trying to get the image from the cell (NOT WORKING)
var fotosToCopy = origen.getRange(personajeRow,2).getValue(); //I've tried .getFormula() with no results; origen is the search range, personajeRow is the row to do the search and both work.
// This is what I'm using to put the image in the document
var doc = DocumentApp.openById(cotizacionId); // cotizacionId is working
var body = doc.getBody();
var foto = body.getImages(); // I'll replace the only existing image
var parent = foto[0].getParent();
parent.insertInlineImage(parent.getChildIndex(foto)+1, fotosToCopy[0]); //fotosToCopy[0] is the issue, it returns "undefined"
foto[0].removeFromParent();
Ideally, the existing in-line-image in the document should be replaced by the image-in-cell from the spreadsheet. The error I get is: "Execution failed: Cannot convert Array to Element".
Any idea?
so I haven't coded this very cleanly but it should give you somehtign close to what you want, but first an explanation:
Google Sheets doesn't have the capacity to return the blob of an image, only a reference to the image, but Google Drive does.
My solution below takes the blob of the FIRST image in the Google Drive folder and adds it to the Document based on the DocID I provide to the function:
function retriveFolder(folderName,imageName,docID){
var imageFolder = DriveApp.getFoldersByName(folderName).next();
var firstImageinFolder = imageFolder.getFilesByName(imageName).next();
var imageBlob = firstImageinFolder.getBlob();
DocumentApp.openById(docID).getBody().insertImage(1, imageBlob);
}
I hope this helps, best I could come up with when I had the same problem. Not ideal but should be a suitable workaround.

correctly insert chart from Google Sheet into Document using Google Apps Script

I want to copy charts from my spreadsheet to a document using Google apps script.
Inserting the charts works, but there is an issue with a) permissions and b) formatting.
Charts can be inserted as follows:
var b = d.getBody();
var charts = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("charts").getCharts();
for (var i in charts) {
b.appendImage(charts[i]);
Logger.log(charts[i].getBlob().getName()); // correct: "chart.png"
}
When I manually copy the chart and paste it in the document, the formatting is exactly as in the spreadsheet.
when I copy using the script, formatting looks very strange or even causes an error (for the line chart with dates on the x-axis it shows an image with the text Data column(s) for axis #1 cannot be of type string)
Top row is manually copied, bottom row is the result of the script.
The second -related?- issue: the spreadsheet needs to be shared ("anyone with the link can view"), otherwise it shows the image (correct name, width, height, etc.) as an error message: User not signed-in. Sign in.
Any suggestions how to insert the chart with the correct formatting and without having to share the spreadsheet?
Stefan pointed me in the right direction (thanks!).
It appears the rendering is done quite differently when pasting/saving images.
Different axis settings, colors, theme, etc.
I ended up manually creating the chart. E.g. for the first bar chart, the following results in a chart that appears the same in the spreadsheet and in the document:
var chart = dest.newChart();
chart
.setChartType(Charts.ChartType.BAR)
.addRange(myrange)
.setPosition(2,8,0,0)
.setOption("theme","maximized")
.setOption("colors",["#3366CC","#FF9900","#DC3912","#109618"])
.setOption('isStacked', true)
.setOption('width', 500)
.setOption('height', 130)
.setOption('hAxis.viewWindow.max', countActions)
.setOption('vAxis.gridlines.count', 0)
.setOption('legend', {position: 'in', textStyle: {fontSize: 12}})
var chart = chart.build();
dest.insertChart(chart);
I also had to change the data range, as it appears the following chart settings can not be set manually.
switch rows/columns
use first row as header
To solve that I have manually transposed the range in the spreadsheet (=TRANSPOSE(original_range)) and let myrange point to that new range, and I have added an empty column so that one is used as an empty header.
I have not looked at the line chart yet, it could be the Chart API can not create a timeline in the same way as the Spreadsheet does.
For what its worth I just used the original script in a simple report builder that takes data and charts from a Google Sheet and auto-generates a report containing them for any user. It worked very easily. Was a slightly modified version of the following
var charts =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("charts").getCharts();
for (var i in charts) {
doc.getBody.appendImage(charts[i]);
Logger.log(charts[i].getBlob().getName())};
where in my script "doc" is a var that repr
Have a look at:
Reading title of Graph
When I was playing around, I remember having issues as well like you described. When I made sure all the required fields were added in the graph (so no skipping of data elements), it worked fine.
Strangly, skipping data elements didn't seem to cause issues in the graph (neither with manually copying & pasting).

Is there a way to remove a script from a doc (using the new doc embedded script)

I developed a script extension that uses a Google doc as template AND as script holder.
It gives me a very nice environment to implement a mail merge application (see below).
At some point I use the DocsList class makeCopy(new Name) to generate all the docs that will be modified and sent. It goes simply like that :
var docId=docById.makeCopy('doc_'+Utilities.formatString("%03d",d)).getId();
Everything works quite nicely but (of course) each copy of the template doc contains a copy of the script which is obviously not necessary ! It is also a bit annoying since each time I open a copy to check if data are right I get the sidebar menu that opens automatically which is a time consuming process ...
My question is (are) :
is there any way to remove the embedded script from the copy ? (that would be simple)
or should I copy all the doc elements from the template to an empty document ? (which is also a possible way to go but I didn't try and I don't know what will be in this doc in real life use...
Shall I get a perfect clone in any case ?)
I've read the doc and didn't find any relevant clue but who knows ? maybe I missed something obvious ;-)
below is a reduced screen capture to show the context of this question :
Following Henrique's suggestion I used a workaround that prevents the UI to load on newly created documents... (thanks Henrique, that was smart ;-)
The function that is called by onOpen now goes like that :
function showFields() {
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
var find = body.findText('#'); // the new docs have no field markers anymore.
if(find != null){ // show the UI only if markers are present in the document.
var html = HtmlService.createHtmlOutputFromFile('index')
.setTitle("Outils de l'option Publipostage").setWidth(370);
ui.showSidebar(html);
}
}

Displaying Google Spreadsheets data in Google Sites as HTML?

I have a google spreadsheet and I'm trying to build a webpage using Google sites. I don't want to embed the whole sheet, or even a range of cells. I just want my webpage to display text from some cells in the spreadsheet, and I want to be able to style that text using HTML.
For example, in the value in cell A1 is "There are 3 games today".
I want to be able to put this text in my webpage and then give it a font size, alignment, and put it in a box with a border and curved corners (border radius).
I think there may be several ways of acheiving this but the closest I have got is by inserting an 'Apps script gadget' into the page and using the doGet() method:
function doGet(e){
var app = UiApp.createApplication();
var ss = SpreadsheetApp.openById('SPREADSHEET_KEY');
var sheet = ss.getSheetByName("Sheet1");
var range = sheet.getRange('A1');
var dataRange = range.getValue().toString();
app.add(app.createHTML("There are " + dataRange + " games today"))
return app;
}
but I dont know how to then add HTML to the webpage to make it look fancy.
I haven't even been able to set anything within the script e.g. font alignment. I've tried
.setHorizontalAlignment('center')
but I keep getting errors such as "Cannot find method (class)setHorizontalAlignment(string)". Can anyone kindly point me in the right direction?
Many thanks in advance
Most of the style attributes can be set with .setStyleAttributes().
.setStyleAttribute("fontSize","200%");
Note: Instead of writing font-size or margin-left, you need to use camelCase.
.setStyleAttributes({marginLeft:"15px",marginTop:"22px"});
These are just a few examples of how to use this.
In order to use horizontal alignment, you should use
.setHorizontalAlignment(UiApp.HorizontalAlignment.CENTER);
Use the autocomplete feature of Google Scripts to see all the options that you can use.
If you're already familiar with HTML, then consider using HTML templates to pull variables from the spreadsheet into the HTML. Templated HTML