Dynamic section name in EvoHtmlToPdf header - pdf-generation

Is there a way in EvoHtmlToPdf to display the section/subsection of a page in the header/footer (i.e. the text of the "current" h1/h2 tag)?
With wkhtmltopdf and other tools, it is possible to replace special tags via JavaScript and the HTML header template (as described here for example Dynamic section name in wicked_pdf header).
Unfortunately, such a solution does not seem to work with EvoHtmlToPdf.
Here's the HTML code of my header template:
<html id="headerFooterHtml">
<head>
<script>
function substHeaderFooter(){
var vars={};
var searchString = document.location.search;
var debugMessage = document.getElementById("showJavaScriptWasExecuted");
if (debugMessage)
debugMessage.textContent = "Search string: ["+ searchString + "]";
var search_list = searchString.substring(1).split('&');
for(var i in search_list){
var content=search_list[i].split('=',2);
vars[content[0]] = decodeQueryParam(content[1]);
}
var tags=['section','subsection'];
for(var i in tags){
var name = tags[i],
classElements = document.getElementsByClassName(name);
for(var j=0; j<classElements.length; ++j){
classElements[j].textContent = vars[name];
}
}
}
</script>
</head>
<body id="headerFooterBody" onload="substHeaderFooter()">
<div id="showJavaScriptWasExecuted"></div>
<div id="sections">{section} / {subsection}</div>
</body>
Resulting header in PDF
I already added the EvoHtmlToPdf PrepareRenderPdfPageDelegate event handler to my code (if that's the way I have to go) but I don't know how to access the section of the current page there...
Thanks in advance for your help!

Related

Google App Scripts Function to Open URL [duplicate]

Is there a way to write a google apps script so when ran, a second browser window opens to www.google.com (or another site of my choice)?
I am trying to come up with a work-around to my previous question here:
Can I add a hyperlink inside a message box of a Google Apps spreadsheet
This function opens a URL without requiring additional user interaction.
/**
* Open a URL in a new tab.
*/
function openUrl( url ){
var html = HtmlService.createHtmlOutput('<html><script>'
+'window.close = function(){window.setTimeout(function(){google.script.host.close()},9)};'
+'var a = document.createElement("a"); a.href="'+url+'"; a.target="_blank";'
+'if(document.createEvent){'
+' var event=document.createEvent("MouseEvents");'
+' if(navigator.userAgent.toLowerCase().indexOf("firefox")>-1){window.document.body.append(a)}'
+' event.initEvent("click",true,true); a.dispatchEvent(event);'
+'}else{ a.click() }'
+'close();'
+'</script>'
// Offer URL as clickable link in case above code fails.
+'<body style="word-break:break-word;font-family:sans-serif;">Failed to open automatically. Click here to proceed.</body>'
+'<script>google.script.host.setHeight(40);google.script.host.setWidth(410)</script>'
+'</html>')
.setWidth( 90 ).setHeight( 1 );
SpreadsheetApp.getUi().showModalDialog( html, "Opening ..." );
}
This method works by creating a temporary dialog box, so it will not work in contexts where the UI service is not accessible, such as the script editor or a custom G Sheets formula.
You can build a small UI that does the job like this :
function test(){
showURL("http://www.google.com")
}
//
function showURL(href){
var app = UiApp.createApplication().setHeight(50).setWidth(200);
app.setTitle("Show URL");
var link = app.createAnchor('open ', href).setId("link");
app.add(link);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
If you want to 'show' the URL, just change this line like this :
var link = app.createAnchor(href, href).setId("link");
EDIT : link to a demo spreadsheet in read only because too many people keep writing unwanted things on it (just make a copy to use instead).
EDIT : UiApp was deprecated by Google on 11th Dec 2014, this method could break at any time and needs updating to use HTML service instead!
EDIT :
below is an implementation using html service.
function testNew(){
showAnchor('Stackoverflow','http://stackoverflow.com/questions/tagged/google-apps-script');
}
function showAnchor(name,url) {
var html = '<html><body>'+name+'</body></html>';
var ui = HtmlService.createHtmlOutput(html)
SpreadsheetApp.getUi().showModelessDialog(ui,"demo");
}
There really isn't a need to create a custom click event as suggested in the bountied answer or to show the url as suggested in the accepted answer.
window.open(url)1 does open web pages automatically without user interaction, provided pop- up blockers are disabled(as is the case with Stephen's answer)
openUrl.html
<!DOCTYPE html>
<html>
<head>
<base target="_blank">
<script>
const url1 ='https://stackoverflow.com/a/54675103';
const winRef = window.open(url1);
winRef ? google.script.host.close() : window.alert('Allow popup to redirect you to '+url1) ;
window.onload=function(){document.getElementById('url').href = url1;}
</script>
</head>
<body>
Kindly allow pop ups</br>
Or <a id='url'>Click here </a>to continue!!!
</body>
</html>
code.gs:
function modalUrl(){
SpreadsheetApp.getUi()
.showModalDialog(
HtmlService.createHtmlOutputFromFile('openUrl').setHeight(50),
'Opening StackOverflow'
)
}
Google Apps Script will not open automatically web pages, but it could be used to display a message with links, buttons that the user could click on them to open the desired web pages or even to use the Window object and methods like addEventListener() to open URLs.
It's worth to note that UiApp is now deprecated. From Class UiApp - Google Apps Script - Google Developers
Deprecated. The UI service was deprecated on December 11, 2014. To
create user interfaces, use the HTML service instead.
The example in the HTML Service linked page is pretty simple,
Code.gs
// Use this code for Google Docs, Forms, or new Sheets.
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.createMenu('Dialog')
.addItem('Open', 'openDialog')
.addToUi();
}
function openDialog() {
var html = HtmlService.createHtmlOutputFromFile('index')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showModalDialog(html, 'Dialog title');
}
A customized version of index.html to show two hyperlinks
<a href='http://stackoverflow.com' target='_blank'>Stack Overflow</a>
<br/>
<a href='http://meta.stackoverflow.com/' target='_blank'>Meta Stack Overflow</a>
Building of off an earlier example, I think there is a cleaner way of doing this. Create an index.html file in your project and using Stephen's code from above, just convert it into an HTML doc.
<!DOCTYPE html>
<html>
<base target="_top">
<script>
function onSuccess(url) {
var a = document.createElement("a");
a.href = url;
a.target = "_blank";
window.close = function () {
window.setTimeout(function() {
google.script.host.close();
}, 9);
};
if (document.createEvent) {
var event = document.createEvent("MouseEvents");
if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1) {
window.document.body.append(a);
}
event.initEvent("click", true, true);
a.dispatchEvent(event);
} else {
a.click();
}
close();
}
function onFailure(url) {
var div = document.getElementById('failureContent');
var link = 'Process';
div.innerHtml = "Failure to open automatically: " + link;
}
google.script.run.withSuccessHandler(onSuccess).withFailureHandler(onFailure).getUrl();
</script>
<body>
<div id="failureContent"></div>
</body>
<script>
google.script.host.setHeight(40);
google.script.host.setWidth(410);
</script>
</html>
Then, in your Code.gs script, you can have something like the following,
function getUrl() {
return 'http://whatever.com';
}
function openUrl() {
var html = HtmlService.createHtmlOutputFromFile("index");
html.setWidth(90).setHeight(1);
var ui = SpreadsheetApp.getUi().showModalDialog(html, "Opening ..." );
}
I liked #Stephen M. Harris's answer, and it worked for me until recently. I'm not sure why it stopped working.
What works for me now on 2021-09-01:
function openUrl( url ){
Logger.log('openUrl. url: ' + url);
const html = `<html>
<a id='url' href="${url}">Click here</a>
<script>
var winRef = window.open("${url}");
winRef ? google.script.host.close() : window.alert('Configure browser to allow popup to redirect you to ${url}') ;
</script>
</html>`;
Logger.log('openUrl. html: ' + html);
var htmlOutput = HtmlService.createHtmlOutput(html).setWidth( 250 ).setHeight( 300 );
Logger.log('openUrl. htmlOutput: ' + htmlOutput);
SpreadsheetApp.getUi().showModalDialog( htmlOutput, `openUrl function in generic.gs is now opening a URL...` ); // https://developers.google.com/apps-script/reference/base/ui#showModalDialog(Object,String) Requires authorization with this scope: https://www.googleapis.com/auth/script.container.ui See https://developers.google.com/apps-script/concepts/scopes#setting_explicit_scopes
}
https://developers.google.com/apps-script/reference/base/ui#showModalDialog(Object,String) Requires authorization with this scope: https://www.googleapis.com/auth/script.container.ui See https://developers.google.com/apps-script/concepts/scopes#setting_explicit_scopes

Windows IoT Core on Raspberry PI default webserver

Have someone found how to make a similar webserver as the default IoT Core one? The most similar example found is this but when I try to insert some javascript in the page, is not recognized. In the default webserver of the IoT Core there are a lot of js and jQuery scripts that runs very well.
Someone have ideas please?
Thanx a lot
Based on this sample, you can add a HTML file to your project and use this HTML file host the content of the web page, then insert some javascript in it.
HTML file:
<!DOCTYPE html>
<html>
<head>
<title>Background Message</title>
</head>
<body>
Hello from the background process!<br />
<script type="text/javascript">
var myVariable = 'Hello, I come from script!';
window.alert(myVariable);
</script>
</body>
</html>
You need edit part of code like this:
using (var response = output.AsStreamForWrite())
{
string page = "";
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
var file = await folder.GetFileAsync("index.html");
var readFile = await Windows.Storage.FileIO.ReadLinesAsync(file);
foreach (var line in readFile)
{
page += line;
}
page += query;
byte[] bodyArray = Encoding.UTF8.GetBytes(page);
var bodyStream = new MemoryStream(bodyArray);
var header = "HTTP/1.1 200 OK\r\n" +
$"Content-Length: {bodyStream.Length}\r\n" +
"Connection: close\r\n\r\n";
byte[] headerArray = Encoding.UTF8.GetBytes(header);
await response.WriteAsync(headerArray, 0, headerArray.Length);
await bodyStream.CopyToAsync(response);
await response.FlushAsync();
}
After deploying your app to Raspberry Pi, while the app running, you can visit the web server. The result will look like this:

Reloading an Image with delay using javascript

I am failing for 2 days on trying to reload an Image using Java script.
I hope you can help!
the Image is displayed but doesnt Change after the defined 7 secunds...
it's not a server-side Problem while i can see in wireshark that the data isn't even requested by the browser...
is anyone having an idea where my Problem might be?
please see my code below for reference
<html>
<!DOCTYPE html>
<html lang="de-DE">
<head>
<bodyonload="DispayImage()">
<img src="/img/dynamic_live_1.jpg" width="600" height="450" name=Cam>
<script language="JavaScript>
var imageUrl = document.Cam.src;
var random = new Date().getTime();
var delay = 7000;
var counter = 0;
var buffer = new Image;
function DisplayImage()
{
document.Cam.src = buffer.src;
LoadNextImage();
}
function LoadBuffer ()
{
var trickname = imageUrl;
++counter;
trickname += "?counter=" + (random + counter);
buffer.src = trickname;
buffer.onload = DisplayImage;
}
function LoadNextImage()
{
setTimeout("LoadBuffer()", delay);
}
LoadNextImage();
</script>
</body>
</html>
On first sight, your "setTimeout"-call seems to be wrong:
Try
function LoadNextImage()
{
setTimeout(function() {LoadBuffer()}, delay);
}
Also, your body.onload has a wrong call, it says "DispayImage" and not "DisplayImage", but that might be a copy-paste error on your end.
Edit: Just tested the corrected code myself, and here it works (used some local images). One last error I found was that you don't close the "language"-tag:
<script language="JavaScript>
should be
<script language="Javascript">
Or, even better, the "language"-tag is not needed, all browsers use javascript as default when you use "script":
<script>/*Some code here*/</script>

modify html file in .net windows app

I have a map.html file that contains a script for google maps api v3, i've been trying previously trying to run this script using the webbrowser1.DocumentText and Webbrower1.Document.InvokeScript been unsuccessful.
This time i have the map.html hosted on a website, My objective is been able to modify this html file and then run it on my windows application in order to display a desired address.
below is the code of the map.html which is hosted ex: http://url.com/map.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://maps.google.com.mx/maps/api/js?sensor=true&language=es"></script>
<script type="text/javascript">
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
//var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 16,
//center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
//var address = document.getElementById("address").value;
var address = "Miami Beach, Flordia" //Address to modify in order to display
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
if you copy and paste this code in a html it should display Miami Beach, FL
now on my windows application i want to edit this html that is hosted on a website i want to change Miami Beach, Florida to Naples,Florida as an example.
then use a webbrowser on my windows application and display it as Webbrowser1.Navigate("http://url.com/map.html")
your help is very appreciated it.
I did found how to modify an html when it is saved locally on my computer but for what i exactly need this is not a viable way.
thank you,
Leo P.
I would not try to modify the html code. Since the Google Maps code is all JS, I would write a JS function to move the map to the new location.
You can call that function from your application (or even insert it from there).
using mshtml;
//First, navigate to your page:
Webbrowser1.Navigate("http://url.com/map.html")
void Webbrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
//Then call your move function with the new target:
mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)Webbrowser1.Document.DomDocument;
mshtml.IHTMLWindow2 window = (mshtml.IHTMLWindow2)doc.parentWindow;
window.execScript("yourMapMoveFunction('Naples,Florida');");
}
BTW, your link does not show a map...

Using xmlhttprequest in IE only includes the contents of the body tag

When I try to get the contents of a htm file into a div using a xmlhttprequest object in Firefox it includes everything, but in IE it only includes the contents of the body tag. In other words it ignores all the styling (in the head tag) of the page, rendering it ugly.
Is it possible to get the full page when using xmlhttprequest in internet explorer?
edit:
document.getElementById('divtoreceivetheresponse').innerHTML = xmlHTTP.responseText
This line in FF gets the page contents including the <head></head> section.
In IE it just gets the contents inside the <body></body> section.
I got an answer from elsewhere. Basically it does include all the page (not just the body) but IE chooses not to render it (probably the correct behavour)
I therefore worked out some code to extract the css, place it in the head, and place the body stuff in the target div. So both html and css from the external page would be got.
<html><head>
<script type="text/javascript" language="javascript">
function include(lyr,url)
{
if (document.all)
{
try {
var xml = new ActiveXObject("Microsoft.XMLHTTP");
xml.Open( "GET", url, false );
xml.Send()
}
catch (e) {
var xml = new ActiveXObject("MSXML2.XMLHTTP.4.0");
xml.Open( "GET", url, false );
xml.Send()
}
}
else
{
var xml=new XMLHttpRequest();
xml.open("GET",url,false);
xml.send(null);
}
text = xml.responseText;
text = text.replace("<html>","");
text = text.replace("</html>","");
text = text.replace("<head>","");
text = text.replace("</head>","");
text = text.replace("<body>","");
text = text.replace("</body>","");
splittext = text.split("<style type=\"text/css\">");
splittext = splittext[1].split("</style>");
css = splittext[0];
everythingelse = splittext[1];
addCss(css);
document.getElementById(lyr).innerHTML=everythingelse;
}
function addCss(cssCode) {
var styleElement = document.createElement("style");
styleElement.type = "text/css";
if (styleElement.styleSheet) {
styleElement.styleSheet.cssText = cssCode;
} else {
styleElement.appendChild(document.createTextNode(cssCode));
}
document.getElementsByTagName("head")[0].appendChild(styleElement);
}
</script>
</head>
<body onload="include('adiv','test.htm')">
<div id="adiv">sdfgboui hsdguhwruh o ikuy </div>
</body>
</html>
The code is far from perfect, but it does the job and I will probably improve the code bit by bit now that I know it works

Resources