How to pass CSS href to inline CSS in app script? - javascript

UPDATE:
I need to save an HTML webpage as a pdf in my google Drive. I am using app script.
However, the PDF is rendered differently from the HTLM page. I need the PDF to be the same as the HTML. FROM RESEARCH I DISCOVERED THAT EXTERNAL CSS IS NOT RENDERED PROPERLY, ONLY INLINE CSS.
I have an HTML page and I need to transform the external CSS into inline CSS. I need to do this using an app script.
Is it possible?
EDIT: MORE DETAILS -- HERE IS MY FUNCTION IN APPSCRIPT AND MY HTML CSS HEADER
function downloadFile() {
var fileURL = "https://www.....
var folder = "primes"
var fileName = "";
var fileSize = "";
var response = UrlFetchApp.fetch(fileURL, {
headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() },
})
var htmlBody = response.getContentText();
var rc = response.getResponseCode();
if (rc == 200) {
var blob = Utilities.newBlob(htmlBody,
MimeType.HTML).getAs('application/pdf').setName('Nota.pdf');
var folder = DriveApp.getFolderById("1gBA8YCs3PH7v7CNl3nlsjNqYzhOxhjYa");
if(folder != null){
var file = folder.createFile(blob);
fileName = file.getName()
fileSize = file.getSize()
}
}
var fileInfo = {'rc':rc,"filename": fileName, "fileSize":fileSize}
Logger.log(fileInfo)
}
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Bling - </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://www.bling.com.br/libs/jquery-1.9.1.min.js" type="text/javascript"></script>
<script type="text/javascript" src="https://www.bling.com.br/libs/utils-1632934481.js"></script> <link rel="stylesheet" type="text/css" href="https://www.bling.com.br/styles/danfe.css" />
<style>
table.grid tr td{
/*padding:2px;*/
The output I get is totally not rendered correctly

Just replace the external css with the actual value with padded style tags.
Script:
var htmlBody = response.getContentText();
// replace external css with the actual css, padded with style tags
var externalCss = `<link rel="stylesheet" type="text/css" href="https://www.bling.com.br/styles/danfe.css" />`;
htmlBody = htmlBody.replace(externalCss, `<style>${UrlFetchApp.fetch('https://www.bling.com.br/styles/danfe.css').getContentText()}</style>`)
var rc = response.getResponseCode();
If this doesn't work due to captcha. (I'm not sure if captcha will cause you some issues when fetching). Copy the actual css (pad it with tags), save it in a file and include it in your string before converting to blob by using:
HtmlService.createHtmlOutputFromFile(filename).getContent()
Output:

Related

How do I grab URL in Apps Script (.gs) and hand it to a .html script?

This is my first question here and I am pretty new to js and html so please excuse if I'm missing something obvious.
Goal: I want to create a script, that creates a Folder in your Google Drive but only if it's not already existing. In that folder it should create a .txt that contains certain information. After that, I want a new Tab to automatically open the URL of the newly created txt-file.
If I insert a normal URL in my .html (like "https://www.google.com") it all works perfectly fine. However I'm stuck at the part where the Apps Script hands over the grabbed Url of the newly created file to my html.
Any help is appreciated!
Google Apps Script Code (Code.gs):
function myFunction() {
var FData = "Very important Data"
var destFolder = DriveApp.getFoldersByName("Folder"); //create Drive folder if not already created
var destFolder = destFolder.hasNext() ?
destFolder.next() : DriveApp.createFolder("Folder");
var fileName = "Status.txt"; //create txt file in that folder and add data to it
var newFile = destFolder.createFile(fileName,FData);
var url = newFile.getUrl(); //?GIVE THIS URL TO openUrl.html?
var htmlOutput = HtmlService.createHtmlOutputFromFile('openUrl').setHeight(100);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Opening...');
}
HTML (openUrl.html):
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
var urlToOpen = url; //insert grabbed Url here
var winRef = window.open(urlToOpen);
google.script.host.close();
</script>
</head>
<body>
</body>
</html>
In your script, how about the following modification?
Google Apps Script side:
function myFunction() {
var FData = "Very important Data"
var destFolder = DriveApp.getFoldersByName("Folder");
var destFolder = destFolder.hasNext() ? destFolder.next() : DriveApp.createFolder("Folder");
var fileName = "Status.txt";
var newFile = destFolder.createFile(fileName, FData);
var htmlOutput = HtmlService.createTemplateFromFile('openUrl');
htmlOutput.url = newFile.getUrl();
SpreadsheetApp.getUi().showModalDialog(htmlOutput.evaluate().setHeight(100), 'Opening...');
}
HTML & Javascript side:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
var urlToOpen = "<?!= url ?>";
var winRef = window.open(urlToOpen);
google.script.host.close();
</script>
</head>
<body>
</body>
</html>
When myFunction() is run, a dialog is opened by HTML including url using HTML template.
Reference:
HTML Service: Templated HTML

Automatically load csv/txt file from local drive into html page as table Javascript

I found a lot of good suggestions on how to load a csv/txt file into a html page into a table, but none of the solutions are working for me. Here is the code I am working with. I have both files located in my C: drive and basically would like to load this csv/txt file and show it on as a table in index.html. Thanks so much!
data.txt
heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2
index.html
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<html>
<head>
<title>Test</title>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: "GET",
url: "data.txt",
dataType: "text",
success: function(data) {processData(data);}
});
});
function processData(allText) {
var allTextLines = allText.split(/\r\n|\n/);
var headers = allTextLines[0].split(',');
var lines = [];
for (var i=1; i<allTextLines.length; i++) {
var data = allTextLines[i].split(',');
if (data.length == headers.length) {
var tarr = [];
for (var j=0; j<headers.length; j++) {
tarr.push(headers[j]+":"+data[j]);
}
lines.push(tarr);
}
}
\\ alert(lines);
}
</script>
</body>
</html>
You can't access local files with JS. That would be serious security vulnerability, because you could send a malicious webpage to a user, which would download their files and send them to someone. As midrizi mentioned in the comments, you'll need a server to download files from there.
As others have noted, you can't automatically read a local file into the browser.
But you can prompt the user to select a file, using the <input type="file"> element.
Once a file has been selected via that input, it can be read via JavaScript.
<label for="file">Select a Text File:</label><br />
<input id="file" type="file" /><br/>
<button onclick="readFile()">Read File</button><br/>
let input = document.getElementById('file');
let contents = document.getElementById('contents');
function readFile () {
let file = input.files[0];
const reader = new FileReader();
reader.onload = function (evt) {
console.log('reader.onload');
contents.innerHTML = String(evt.target.result);
};
reader.readAsText(file);
}
If you can modify the data.txt a bit you can just load it as another script file without need for a server.
Change data.txt to this
var data = `heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2`
And load it as a javascript file before your actual script
<script type="text/javascript" src="data.txt"></script>
Then you can use the variable data which holds your file content without any ajax call.
There is no way you can retrieve a local file if you don't serve it, as pointed out in the comments to your question.
There are approaches you can take to that, though. If you can't serve it by any means, you could create a GitHub repo and upload your file there. Then you can use the link to your raw file:
And you can also take steps to automate that, but it should be easy enough committing your file locally whenever you update it and push it to GitHub. Just in case you're not familiar with Git and GitHub, here's a handy ref.
A word of caution: unless you have total control over the characters that you include in your CSV, parsing them by naively splitting commas like that might result in ugly stuff if the values within contain commas themselves. Some CSV files also come with extra stuff in the beginning of the file (like the sep indicator in the first row, which defines what character to interpret as separator). You may completely ignore these warnings if you're producing the CSV yourself.
Also I noticed your function does not take care of building the actual table, so I changed it so it does. I also used Fetch API to retrieve the data:
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<html>
<head>
<title>Test</title>
</head>
<body>
<script type="text/javascript">
function processData(csv) {
let data = csv.split(/\r\n|\n/).map(v => v.split(','));
let headers = data.shift();
let table = document.createElement('table');
let thead = document.createElement('thead');
table.appendChild(thead);
thead.innerHTML = '<tr><th>' + headers.join('</th><th>') + '</th></tr>';
let tbody = document.createElement('tbody');
table.appendChild(tbody);
for (let row of data) {
tbody.innerHTML += '<tr><td>' + row.join('</td><td>') + '</td></tr>';
}
document.body.appendChild(table);
}
// I uploaded the CSV to a personal repo for this example,
// but you CAN use a local file as long as you *serve* it
fetch("https://raw.githubusercontent.com/gyohza/test/master/so/data.txt")
.then(res => res.text())
.then(text => processData(text));
</script>
</body>
</html>

JavaScript: Read directory from within addEventListener function

I added an event listener to my website which should add a date, time and device-id to the website. These information are included in the filenames of some files located in a directory at the same level as my index.html.
Directory Structure:
- audiofiles
-- date_time_device.wav
-- date2_time2_device2.wav
- scripts
-- scripts.js
- Home.html
Within the head of Home.html I'm calling a addContent() (located in scripts.js) which includes the addEventListener().
This works if I'm inserting hardcoded strings, so it seems that reading from the directory does not work.
It would be great if anybody could steer me into the right direction. Thanks!
Head of Home.html:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://unpkg.com/wavesurfer.js"></script>
<script type="text/javascript" src='scripts/scripts.js'> </script>
<script type="text/javascript" src="js/wavesurfer.js"></script>
<script>
addContent();
</script>
<title>Home</title>
</head>
scripts.js:
function addContent() {
document.addEventListener("DOMContentLoaded", function(event) {
var fs = require('fs');
const files = fs.readdirSync('path/to/audiofiles');
for (i=0;i<3;i++) {
var date = files[i].slice(0,10);
var time = files[i].slice(11,19);
var device = files[i].slice(20,-4);
var TheInnerHTML ="";
TheInnerHTML += "<tr><td> blabla" + 3 + " " + String(date)+"</td><td>"+String(time)+"</td></tr>"+String(device)+"</td></tr><br>";
}
document.getElementById("TheBody").innerHTML = TheInnerHTML;
});
}

Scrape html with js

I'm trying to get the html of www.soccerway.com. In particular this:
that have the label-wrapper class I also tried with: select.nav-select but I can't get any content. What I did is:
1) Created a php filed called grabber.php, this file have this code:
<?php echo file_get_contents($_GET['url']); ?>
2) Created a index.html file with this content:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<meta charset=utf-8 />
<title>test</title>
</head>
<body>
<div id="response"></div>
</body>
<script>
$(function(){
var contentURI= 'http://soccerway.com';
$('#response').load('grabber.php?url='+ encodeURIComponent(contentURI) + ' #label-wrapper');
});
var LI = document.querySelectorAll(".list li");
var result = {};
for(var i=0; i<LI.length; i++){
var el = LI[i];
var elData = el.dataset.value;
if(elData) result[el.innerHTML] = elData; // Only if element has data-value attr
}
console.log( result );
</script>
</html>
in the div there is no content grabbed, I tested my js code for get all the link and working but I've inserted the html page manually.
I see a couple issues here.
var contentURI= 'http:/soccerway.com #label-wrapper';
You're missing the second slash in http://, and you're passing a URL with a space and an ID to file_get_contents. You'll want this instead:
var contentURI = 'http://soccerway.com/';
and then you'll need to parse out the item you're interested in from the resulting HTML.
The #label-wrapper needs to be in the jQuery load() call, not the file_get_contents, and the contentURI variable needs to be properly escaped with encodeURIComponent:
$('#response').load('grabber.php?url='+ encodeURIComponent(contentURI) + ' #label-wrapper');
Your code also contains a massive vulnerability that's potentially very dangerous, as it allows anyone to access grabber.php with a url value that's a file location on your server. This could compromise your database password or other sensitive data on the server.

how to get all files names and sub folder names in a folder in javascript+html?

I want to get all the file names and sub folders names in JavaScript. But, in my code the activeX object method is not working. Could you find the problem in my code please?
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Report Interface</title>
<script type="text/javascript">
function FindFile(FOo)
{
var fs = new ActiveXObject("Scripting.FileSystemObject");
var Folder = fs.GetFolder(FOo);
var FileCollection = Folder.Files;
var Files = new Array();
for(var objEnum = new Enumerator(FileCollection); !objEnum.atEnd(); objEnum.moveNext())
{
strFileName = objEnum.item();
alert(strFileName);
}
}
</script>
</head>
<body>
<script type="text/javascript">
window.onload = function()
{
var file_path = "C:/xampp/tomcat/webapps/brt-example/report"; // Starting directory
FindFile(file_path);
}
</script>
</body>
</html>
Only IE has support for ActiveX, it can't be accessed with default security settings due to security reasons, if you have to run this -
Go to IE Tools > Internet options > Security > Custom Level >
Under the ActiveX controls and plug-ins, select\ enable for Initializing and Script ActiveX controls not marked as safe for scripting.

Categories