Writing a custom file format downloader in Google Spreadsheets - javascript

What I'm aiming to do is write something akin to the File > Download as > * functionality currently in Google Spreadsheets, but I want it to be in a custom format.
Specifically, I want to turn a spreadsheet of financial transactions into an QIF or OFX file for importing into accounting software. In essence, pushing a button on the UI will download a QIF/OFX version of the currently open spreadsheet.
I have tried the following so far:
Publishing a service (via implementing doGet) that uses ContentService to create the custom file and return it as a download using TextOutput.downloadAsFile(). This works if I call the endpoint directly using my browser.
Tried redirecting the browser to the Service's URL via window.location, but that doesn't seem to be available in the context of the App Script.
Tried using UrlFetchApp.fetch to have the front-end (the spreadsheet) have the browser navigate to the URL for the service. This didn't work either (not really surprising).
So, is this the right approach here? How else can I attack this?

Looks like this is what you have to do.
Create a UiApp
Add a link to the download inside that app.
Show the UiInstance on the spreadsheet
It's a little bit bulky, but it seems the be the cleanest solution.
function downloadAsWhatever() {
var app = UiApp.createApplication();
app.add(app.createAnchor("Download the file now!", "https://script.google.com/macros/s/[...]/exec"))
SpreadsheetApp.getActiveSpreadsheet().show(app.setWidth(300).setHeight(150));
}
You can set the size of the app to whatever you'd like. I chose to set it smaller so it takes up less space on the Spreadsheet screen.
For now the best way to direct a user to a new page is to create an anchor widget and have them click it. We understand that this is not an ideal user experience, but it should suffice for must use cases.
Source

Related

How to convert editable PDF to non-editable PDF in PHP/NodeJS?

Problem
I would like to know is there any PHP/NodeJS API available to convert editable PDF to non-editable PDF online. We have a client application where we need a scenario where the user downloads the PDF should not able to modify it thought any software (eg. Foxit reader, Adobe)
Basically, we are using PDF-LIB right now and it seems there is no solution for the non-editable pdf API to set access privileges, I have search a lot but does not found any API for that, Am not using the pdf-flatten because we want everything selectable, Appreciate your help.
List of libraries tried and fail to achieve the results
bpampuch/pdfmake issue can't load an existing pdf
PDF-LIB issue can't support permissions
nrhirani/node-qpdf issue File restrictions not working properly
I think flattening the PDF might help you to make it un-editable in case your target is
Just the form fields then you might use this from the PDF-LIB github repo
The entire PDF then, see if pdf-flatten package helps for Node.js
After a lot of research work and tried multiple libraries in PHP/Node. I don't found any library that is mature enough to proceed with that, so I decided to make an API that will build in different technology C# and Java
Solution
we post the PDF URL through API, the API download that file, and apply for multiple permission according to the dataset.
Library
the library we choose is ASPOSE
// These can be true/false
config.IsPrint = true;
// Document is allowed to be changed.
config.IsModify = false;
// Annotation is allowed.
config.IsAnnot = true;
// Form filling is allowed.
config.IsFillForm = true;
// Content extraction is allowed.
config.IsExtract = true;

python javascript scrape automatically

Python novice here.
I am trying to scrape company information from the Dutch Transparency Benchmark website for a number of different companies, but I'm at a loss as to how to make it work. I've tried
pd.read_html(https://www.transparantiebenchmark.nl/en/scores-0#/survey/4/company/793)
and
requests.get("https://www.transparantiebenchmark.nl/en/scores-0#/survey/4/company/793")
and then working from there. However, it seems like the data is dynamically generated/queried, and thus not actually contained in the html source code these methods retrieve.
If I go to my browser's developer tools and copy the "final" html as shown there in the "Elements" tab, the whole information is in there. But as I'd like to repeat the process for several of the companies, is there any way to automate it?
Alternatively, if there's no direct way to obtain the info from the html, there might be a second possibility. The site allows to download the information as an Excel-file for each individual company. Is it possible to somehow automatically "click" the download button and save the file somewhere? Then I might be able to loop over all the companies I need.
Please excuse if this question is poorly worded, and thank you very much in advance
Tusen takk!
Edit: I have also tried it using BeautifulSoup, as #pmkroeker suggested. But I'm not really sore how to make it work so that it first runs all the javascript so the site actually contains the data.
I think you will either want use a library to render the page. This answer seems to apply to python. I will also copy the code from that answer for completeness.
You can pip install selenium from a command line, and then run something like:
from selenium import webdriver
from urllib2 import urlopen
url = 'http://www.google.com'
file_name = 'C:/Users/Desktop/test.txt'
conn = urlopen(url)
data = conn.read()
conn.close()
file = open(file_name,'wt')
file.write(data)
file.close()
browser = webdriver.Firefox()
browser.get('file:///'+file_name)
html = browser.page_source
browser.quit()
I think you could probably skip the file write and just pass it to that browser.get call, but I'll leave that to you to find out.
The other thing you can do is look for the ajax calls in a browser developer tool. i.e. when using chrome the 3 dots -> more tools -> developer tools or press something like F12. Then look at the network tab. There will be various requests. You will want to click one, click the Preview tab, and then go through each until you find a response that looks like json data. You are effectively look for their API calls that they used to get the data to generate things. Once you find one, click the Headers tab and you will see a Request URL.
i.e. this https://sa-tb.nl/api/widget/chart/survey/4/sector/38 has lots of data
The problem here is it may or may not be repeatable (API may change, id's may change). You may have a similar problem with just HTML scraping as the HTML could change just as easily.

D3 visualization on local machine without HTML server?

I'm a total novice in web development. I'm interested in using D3 to create interactive visualizations for my (insurance) work, not for sharing on web. The visualization would need to be pretty self-contained so non-tech-savvy business users can view it without special software setup--just the usual browser, internet access, and access to the same LAN locations I have. Below is my initial investigation into viability.
1) I can save this HTML example to my local machine and view the chart in a browser, no probs: https://bl.ocks.org/mbostock/b5935342c6d21928111928401e2c8608
2) Then I tried a visualization that uses a data file.
https://bl.ocks.org/mbostock/2838bf53e0e65f369f476afd653663a2
I went to the data source website and downloaded the .csv. Simply changing the file address in the d3.csv() command to my local drive didn't work (as I mentioned I'm a novice)
Can anyone show me how to make (2) work locally? I found some related answers
Loading local data for visualization using D3.js
Reading in a local csv file in javascript?
but still over my head--if someone can work the example (2) above I can probably understand better...
There are two techniques you can use to load d3 data without a server:
load the data yourself without using d3.csv() helpers.
use data-urls with d3.csv() to avoid server loading.
Loading the data yourself without d3.csv()
Your first example: Stacked Negative Values works because data is defined at the top of the page without using d3.csv():
var data = [...];
...
// d3 operates on the data
Your second example: Nested TreeMap doesn't work because the data is loaded by d3.csv() which takes a path, which ordinarily takes assumes a server:
d3.csv("Home_Office_Air_Travel_Data_2011.csv", type, function(error, data) {
...
// work on data within the anon function passed to d3.csv.
Using data-urls with d3.csv()
However, if you use a data-url as the path, you can get this to work without a server:
var data = [...];
var dataUri = "data:text/plain;base64," + btoa(JSON.stringify(data));
d3.csv(dataUri, function(data){
// d3 code here
});
Adapted from: Create data uri's on the fly?
As an aside, you may be interested in a Middleman plugin I wrote that creates self-contained d3 HTML pages that can be run from the file system without a server using these approaches:
https://github.com/coldnebo/middleman-static-d3
Most modern browsers (chrome, mozilla) have full built in html5, css3, and javascript support without need of a webserver (this is the preferred route for developement).
For example, if you're using chrome all you need to do is set the allow local file access flag: How to launch html using Chrome at "--allow-file-access-from-files" mode?
In mozilla set the about:config key security.fileuri.strict_origin_policy to false.
Again, these are options for loading local files without a webserver, but setting up a webserver is a relatively simple task that is the most recommended route.
you'll need to run a local server like python's SimpleHTTPServer to get this to work locally. once you've got it installed, it's as simple as running a single command in your terminal.
however, since you said that your end users should be able to access it through the browser, do you mean that you'll host it online? if so, they'll be able to view it correctly on the server
Notice how in the first example the data in hard coded into the html page with the variable name data? The data is already here so you won't need a server to go and fetch the data. On the other hand, in second example the data is not hardcoded and is fetched with a server. If you want this to work like the first example you will have to hard code the data into the web page.
You may want to use SERVED by Ian Johnson, its pretty good.
http://enjalot.github.io/served/

Load image for HTML img element from JSON property while URL not directly accessible

OK, this one is rather complicated to explain, which explains the verbose title:
In my Objective C application I generate a JSON string to hold all of my properties for the objects I need to draw in the ARchitect browser of the wikitude SDK (as far as I know the Wikitude SDK only handles JSON) via:
NSString *javaScript = [self convertPoiModelToJson:self.poiData.pois];
NSString *javaScriptToCall = [NSString stringWithFormat:#"newData('%#')", javaScript];
One particular object I am interested in is stored as a string in that JSON string, it's the URL to an image. However, this image is behind a password protected area on our webserver and the app handles the authentication.
The problems start when I am in the ARchitect Browser, which is basically a .html file with calls to specific wikitude javascript functions to build the augmented reality world and show it in a UIWebView in the app. I want to show that image when a POI in the augmented view is clicked in the footer popup which is a basic html div container. So now I have a URL to an image resource on the webserver, which I cannot directly access with
document.getElementById("thumb").src = jsonObject.thumbUrl;
because of the authentication needed and the only way I was successful to load that image was via the var poiImage = new AR.ImageResource(jsonObject[i].iconURL, {onError: errorLoadingImage}); method but then I can only display it in the augmented view but not in the footer.
I tried it with providing a static string from some other image in the web or to local resources to the img element in the footer section in the view without problems like that: document.getElementById("thumb").src="marker.png"; and it works fine, also the image is correctly loaded in the augmented view.
I have read about encoding the image (which I can access and download in the objective c part of the app) in base64 and storing that string in an additional JSON property to load it into the src property of the html img element with a <img src="data:image/png;base64,BASE&$_ENCODED_DATA"></img> but this seems like a really dirty and overly impractical workaround/hack for what I try to accomplish. Also I don't know if it's a better idea to start reading about how to implement the authentication to access that image in the protected area of the webserver or rather begin implementing the ugly base64 encoding or continue searching for alternatives.
I'm not asking for a solution but rather for suggestions what possibilities I have left to access that image. Since I ran out of ideas, any help is appreciated.
Thank you!
Short summary:
image accessible and downloaded in objective c part
image is accessible with the AR.ImageResource method of the wikitude SDK (but not needed)
image cannot be accessed directly via the url from javascript because authentication is needed
(I hope my question is comprehensible, feel free to ask If something is unclear, especially since English is not my first language and it would be even complicated to explain that in German..)
Have you tried downloading the image in Objective-C / Cocoa, store it locally on your iOS device and pass the local path of the image via JSON into your Architect World?
You can then load the local image with your AR.ImageResouce and your div container.
Ok, let's think a bit about this, as it seems like a good mess.
If I'm understanding well your problem, all is about your javascript code needing to reach a url where an image is located, being unable to do so because that place requires some sort of validation to access.
In this scenario I'd look for moving images to a place out of the restricted site. Maybe trying to save them from the objective-C part into one public place that's reachable by javascript. This may be tricky as the I/O operation could slow your code execution... Of course you'll always have the option to move those images just outside of the restricted area but I supose that's not feasible as you could suposed that solution by yourself.
Other way... if your environment configuration allows it (I fear there isn't enough info about it on the question) is to try to execute your javascript part (I wonder if it's enclosed into a webpage executed from a webserver) with a user with permissions into the restricted area. This, of course, could be totally a no-no depending on what your javascript part does and why your restricted area is protected by validation.
If you don't want to move out the files, copy them temporarily gives performance problems and errors, and user impersonation through the javascript executing user is not an option I fear your unique alternative is to efectively try to pass a binary stream of data with the image through the JSON string... dirty...
Looks like wikitude maintains 2 browser contexts: the host browser that loaded your HTML and an embedded browser-like object (or iframe or proxy server) represented by the UIWebView instance.
Only one of those (not clear which from your discussion) has the user/pass for access to your image. You will need to call something to repeat the authentication step or transfer credentials to the other context.

Sending google visualization chart to email

Can we send Google Visualization chart to an email client?
I tried to copy paste the javascript code while sending the email, but its been removed on the fly by gmail.
Thanks and Regards.
Disclaimer: I'm Image-Charts founder.
6 years later! Google Image-Charts is deprecated since 2012, and as an indiehacker, I don't want to rewrite from scratch an image generation backend each time I started a new SaaS to just be able to send charts in email...
That's why I've built Image-charts 👍 and added gif animation on top of it 🚀(chart animations in emails are awesome!!), no more server-side chart rendering pain, no scaling issues, it's blazing fast, 1 URL = 1 image chart.
https://image-charts.com/chart
?cht=bvg
&chd=t:10,15,25,30,40,80
&chs=700x300
&chxt=x,y
&chxl=0:|March '18|April '18|May '18|June '18|July '18|August '18|
&chdl=Visitors (in thousands)
&chf=b0,lg,90,05B142,1,0CE858,0.2
&chxs=1N**K
&chtt=Visitors report
&chma=0,0,10,10
&chl=||||+33% !|x2 !
I ran into this problem as well. In order to send a chart in email, you need to render it as an image because email clients strip Javascript.
If you're using Google Charts, you'll have to run the Javascript and then export it using getImageURI. To automate this, you need a headless renderer like puppeteer.
The solution to the problem is open source. I wrapped chart rendering in a library and web server: https://github.com/typpo/quickchart. This web service handles the rendering details, all you do is call the API with your data.
For example, define your chart in the query parameters:
https://quickchart.io/chart?width=500&height=300&c={type:'bar',data:{labels:['January','February','March','April','May'],datasets:[{label:'Dogs',data:[50,60,70,180,190]},{label:'Cats',data:[100,200,300,400,500]}]}}
The above URL renders this image:
Hope this helps!
Google charts could be published in 2 ways:
as an Image. Edit Chart-> Publish Chart-> Format : image. An image link is generated. This image link could be either used in any html page or could be embedded in any email.
as an Interactive Chart. Edit Chart-> Publish Chart-> Format : Interactive Chart. In this case javascript code has to be inserted. This could only be published in html pages. This could not be attached in email body as most email servers/clients do not process javascript code (AFAIK).
3.5 years later... :)
My team at Ramen recently spun out some internal functionality into a standalone product that does just this: https://ChartURL.com
You can generate charts on the fly using an "Encrypted URL" scheme, or you can send us huge amounts of data and return a Short URL that'll resolve to an image.
It was built on top of C3js.org so there's a ton of flexibility in what you can generate.
These URLs can be used in web apps & mobile apps, but the original intent was email charts so I hope this helps!
There is very little JS support in email clients. so you will have to use an image chart. But you could wrap the chart in a link to the svg version.
Doesn't Google Charts have an API where you can just build a URL and it returns an image - no Javascript needed? It certainly used to. If you can use that, then:
a) Just put the URL in the email and let the users email client get it
b) Fetch the image with CURL and attach to the email.

Categories

Resources