Centering image in Excel - html

I've been trying to center an image in an Excel export file using Classic ASP. I tried everything and resorted to CSS. CSS didn't work (examples below):
img {
position: absolute;
top: 0; bottom:0; left: 0; right:0;
margin: auto;
}
and
img.center {
display: block;
margin: 0 auto;
}
I tried putting the image in a div and centering the div. That also didn't work. I have the image in an img tag like this:
<img border=0 id= "img" name= "img" src="pic.jpg" height ="100" width= "1000">
When I export the file to Excel and open it, the picture is always to the very left.

While simple Excel files can be created through ASP Classic simply by setting the headers for the page, you will often need more control.
Please take a look at this: http://www.crydust.be/blog/2009/03/02/generate-excel-files-in-asp-classic/
Code repostedform Kristof Neirynck's blog here:
<%#LANGUAGE="JAVASCRIPT" CODEPAGE="65001"%>
<%
function getData(connectionString, sql){
var result = null;
var adStateOpen = 1;
var connection = new ActiveXObject("ADODB.CONNECTION");
try{
connection.Open(connectionString);
} catch(e1){
return null;
}
if (connection.State !== adStateOpen) {
return null;
}
try{
var recordset = connection.Execute(sql);
} catch(e2){
return null;
}
if (!recordset.EOF) {
result = recordset.GetRows().toArray();
recordset.Close();
}
recordset = null;
connection.Close();
connection = null;
return result;
}
function writeCsvHttpHeaders(filename){
Response.ContentType = "text/csv";
Response.Charset = "utf-8";
Response.AddHeader("Content-Disposition",
"attachment; filename="+filename+".csv");
}
function writeXlsHttpHeaders(filename){
Response.ContentType = "application/vnd.ms-excel";
Response.Charset = "utf-8";
Response.AddHeader("Content-Disposition",
"attachment; filename="+filename+".xls");
}
function getXlsStart(){
return ""
+ "<html>\n"
+ "<head>\n"
+ "<meta http-equiv=\"Content-Type\" "
+ "content=\"text/html; charset=UTF-8\">\n"
+ "<style type=\"text/css\">\n"
+ "html, body, table {\n"
+ " margin: 0;\n"
+ " padding: 0;\n"
+ " font-size: 11pt;\n"
+ "}\n"
+ "table, th, td { \n"
+ " border: 0.1pt solid #D0D7E5;\n"
+ " border-collapse: collapse;\n"
+ " border-spacing: 0;\n"
+ "}\n"
+ "</style>\n"
+ "</head>\n"
+ "<body>\n"
+ "<table>\n"
+ "";
}
function getXlsEnd(){
return ""
+ "</table>\n"
+ "</body>\n"
+ "</html>"
+ "";
}
function csvEscape(val){
if (typeof val === "number") {
return val.toString(10).replace(".", ",");
} else if (typeof val === "string") {
if (val.indexOf("\"") !== -1) {
return "\""+val.replace(/"/g, "\"\"")+"\"";
} else if (val.indexOf(";") !== -1) {
return "\""+val+"\"";
} else {
return val;
}
} else if (val === null) {
return "#NULL#";
} else if (val === undefined) {
return "#UNDEFINED#";
} else {
return "#ERROR#";
}
}
function writeCsv(filename, data, columnCount){
writeCsvHttpHeaders(filename);
// utf-8 BOM (very important for special characters)
Response.Write("\uFEFF");
for (var i=0, il=data.length; i<il; i+=columnCount) {
for (var j=0; j<columnCount; j++) {
Response.Write(csvEscape(data[i+j]));
if (j !== columnCount-1) {
Response.Write(";");
}
}
Response.Write("\n");
// prevent Response Buffering Limit Exceeded
if (i % 1000 === 0) {
Response.Flush();
}
}
}
function xlsEscape(val){
if (typeof val === "number") {
return val.toString(10).replace(".", ",");
} else if (typeof val === "string") {
return Server.HTMLEncode(val);
} else if (val === null) {
return "#NULL#";
} else if (val === undefined) {
return "#UNDEFINED#";
} else {
return "#ERROR#";
}
}
function writeXls(filename, data, columnCount){
writeXlsHttpHeaders(filename);
Response.Write(getXlsStart());
for (var i=0, il=data.length; i<il; i+=columnCount) {
Response.Write("<tr>");
for (var j=0; j<columnCount; j++) {
Response.Write("<td>");
Response.Write(xlsEscape(data[i+j]));
Response.Write("</td>");
}
Response.Write("</tr>\n");
// prevent Response Buffering Limit Exceeded
if (i % 1000 === 0) {
Response.Flush();
}
}
Response.Write(getXlsEnd());
}
function main(){
var filetype = Request.QueryString("filetype")();
Var connectionString = "Provider=SQLOLEDB.1;"
+ "Data Source=LAPTOP\\SQLEXPRESS;"
+ "User ID=internal;"
+ "Password=internal;"
+ "Initial Catalog=trees_in_sql";
Var sql = ""
+ "SELECT id \n"
+ ", name \n"
+ "FROM People \n"
+ ";";
var filename = "filename";
var columnCount = 2;
var data = getData(connectionString, sql);
if (data !== null) {
Response.Clear();
if (filetype === "csv") {
writeCsv(filename, data, columnCount);
} else {
writeXls(filename, data, columnCount);
}
} else {
Response.Write("Error, no data found");
}
Response.End();
}
main();
%>
.
IMPORTANT
Regarding images specifically, you should look at this: http://www.experts-exchange.com/Programming/Languages/Scripting/ASP/Q_27115638.html
From the above link:
<!--#include file="functions.asp"-->
<%
response.ContentType = "application/vnd.ms-excel"
thedate = CStr(Now())
groupid = request.querystring("groupid")
GroupName = getGroupName(groupid)
datetimestring = Replace(FormatDateTime(Now(), vbShortDate), "/", "-") & "_" & Replace(FormatDateTime(Now(), vbShortTime), ":", "")
response.AddHeader "Content-Disposition", "attachment;filename=GroupAttendanceExport_" & GroupName & "_" & datetimestring & ".xls"
response.write "<html><body><table>"
response.write "<tr><td><img border=0 src='https://www.example.org/xxx_Logo_small.jpg'></td></tr>"
response.write "<tr><td></td></tr>"
response.write "<tr><td></td></tr>"
response.write "<tr><td></td></tr>"
response.write "<tr><td></td></tr>"
response.write "<tr><td></td></tr>"
response.write "<tr><td > Attendance</td></tr>"
response.write "</table>"
MORE CODE HERE
………
………
………
………
response.write "</body></html>"
.
UPDATE
It sounds like you need to use OpenXML instead of HTML.
Here is an example of how to insert an image into a specific cell using OpenXML: https://social.msdn.microsoft.com/Forums/office/en-US/157e2fab-ed30-43a5-9824-e144d673a5b7/insert-images-into-specific-excel-cells-using-openxml?forum=oxmlsdk

Related

Extracting Google Meet URL from Google Calendar API [duplicate]

I want to create a line notify which can send the event detail from my google calendar everyday.
I can get the title, description, location...etc, but I don't see the conference data in calendar API.
I use Google Apps Script to run the code.
Here is my code.
const Now = new Date();
const Start = new Date(new Date().setHours(0, 0, 0, 0));
const End = new Date(new Date().setHours(23, 59, 59, 999));
const calendarData = calendar.getEvents(Start, End);
function Notify() {
var NotifyContents = '';
var i = 1;
calendarData.forEach(item =>{
if (Now <= item.getStartTime()) {
NotifyContents += (item.getTitle() != "") ? ("\n" + i+". "+ item.getTitle() + "\n") : ("\n\nNo Title\n");
NotifyContents += (item.getDescription() != "") ? item.getDescription() + "\n" : "";
NotifyContents += (item.getStartTime() != "" && item.getEndTime() != "") ? "Time:" + item.getStartTime().toLocaleTimeString() + "-" + item.getEndTime().toLocaleTimeString() + "\n": "";
NotifyContents += (item.getconferencedata() != "") ? ("\n" + i+". "+ item.getconferencedata()) : ("No Conference\n");
i++;
}
}
)
if (typeof NotifyContents === 'string' && NotifyContents.length === 0) {
return;
}
NotifyTokens.forEach(function(value){
UrlFetchApp.fetch("https://notify-api.line.me/api/notify", {
"method" : "post",
"payload" : {"message" : NotifyContents},
"headers" : {"Authorization" : "Bearer " + value}
});
});
}
Reference - Calendar API Link
In order to retrieve the meet link from the event, it seems that in the current stage, Calendar API is required to be used. When this is reflected in your script, how about the following modification?
Modified script:
Before you use this script, please enable Calendar API at Advanced Google services.
From:
var NotifyContents = '';
var i = 1;
calendarData.forEach(item => {
if (Now <= item.getStartTime()) {
NotifyContents += (item.getTitle() != "") ? ("\n" + i + ". " + item.getTitle() + "\n") : ("\n\nNo Title\n");
NotifyContents += (item.getDescription() != "") ? item.getDescription() + "\n" : "";
NotifyContents += (item.getStartTime() != "" && item.getEndTime() != "") ? "Time:" + item.getStartTime().toLocaleTimeString() + "-" + item.getEndTime().toLocaleTimeString() + "\n" : "";
NotifyContents += (item.getconferencedata() != "") ? ("\n" + i + ". " + item.getconferencedata()) : ("No Conference\n");
i++;
}
}
)
To:
const eventList = Calendar.Events.list(calendar.getId(), { timeMin: Start.toISOString(), timeMax: End.toISOString(), maxResults: 2500 }).items.reduce((o, e) => (o[e.id] = e.conferenceData.entryPoints.map(({ uri }) => uri).join(","), o), {});
var NotifyContents = '';
var i = 1;
calendarData.forEach(item => {
if (Now <= item.getStartTime()) {
NotifyContents += (item.getTitle() != "") ? ("\n" + i + ". " + item.getTitle() + "\n") : ("\n\nNo Title\n");
NotifyContents += (item.getDescription() != "") ? item.getDescription() + "\n" : "";
NotifyContents += (item.getStartTime() != "" && item.getEndTime() != "") ? "Time:" + item.getStartTime().toLocaleTimeString() + "-" + item.getEndTime().toLocaleTimeString() + "\n" : "";
var eventId = item.getId().split("#")[0];
NotifyContents += eventList[eventId] != "" ? ("\n" + i + ". " + eventList[eventId]) : ("No Conference\n");
i++;
}
});
In this modification, it supposes that calendar has already been declaread. Please be careful about this.
Reference:
Events: list

Alert Value Not Populating Dialog Box

Making a JS/HTML validation form for my website. The form works great but I want to show an alert dialog box showing the users inputs before submitting successfully. I initialize var dataPreview to return if no errors occur, however upon pressing submit, it goes straight to the confirmation page. Any feedback is appreciated!
function validateForm(){
var name = document.contactForm.name.value;
var email = document.contactForm.email.value;
var mobile = document.contactForm.mobile.value;
var address = document.contactForm.address.value;
var birth = document.contactForm.birth.value;
var nameErr = emailErr = mobileErr = addressErr = birthErr = true;
if(name == "") {
printError("nameErr", "Please enter your name");
} else {
var regex = /^[a-zA-Z\s]+$/;
if(regex.test(name) === false) {
printError("nameErr", "Please enter a valid name");
} else {
printError("nameErr", "");
nameErr = false;
}
}
if(email == "") {
printError("emailErr", "Please enter your email address");
} else {
// Regular expression for basic email validation
var regex = /^\S+#\S+\.\S+$/;
if(regex.test(email) === false) {
printError("emailErr", "Please enter a valid email address");
} else{
printError("emailErr", "");
emailErr = false;
}
}
if(mobile == "") {
printError("mobileErr", "Please enter your mobile number");
} else {
var regex = /^[1-9]\d{9}$/;
if(regex.test(mobile) === false) {
printError("mobileErr", "Please enter a valid 10 digit mobile number");
} else{
printError("mobileErr", "");
mobileErr = false;
}
}
if(address == "") {
printError("addressErr", "Please enter your address");
} else {
var regex = /^[a-zA-Z\s]+$/;
if(regex.test(address) === false) {
printError("addresasErr", "Please enter a valid name");
} else {
printError("addressErr", "");
addressErr = false;
}
}
if(birth == "") {
printError("birthErr", "Please enter your birthday");
} else {
var regex = /^[a-zA-Z\s]+$/;
if(regex.test(birth) === false) {
printError("birthErr", "Please enter a valid birthday");
} else {
printError("birthErr", "");
birthErr = false;
}
}
***if((nameErr || emailErr || mobileErr || addressErr || birthErr) == true){
return false;
} else{
var dataPreview = "You have entered the following information: \n" +
"Full Name: " + name + "\n" +
"Email Address: " + email + "\n" +
"Mobile Number: " + mobile + "\n" +
"Address: " + address + "\n" +
"Birthday: " + birth + "\n";
alert(dataPreview);
}
}
</script>

Get total rows filtered by if() statement in google apps scripts

I've got this fn().
Is there any simple way to return the number of filtered rows by this conditional statement in Google app scripts?
function getGlobers(globers, project){
var body = "";
var data = globers.getValues();
for( i = 0; i < data.length; i++ ){
if( data[i][2] == project ){
body += "<tr><td style=" + STYLE.TD + ">" + data[i].join("</td><td style=" + STYLE.TD + ">") + "</td></tr>";
}
}
return body;
}
Thanks.
for example (see comments in code)
function getGlobers(globers, project){
var body = "";
var n = 0; // use a variable to count
var data = globers.getValues();
for( i = 0; i < data.length; i++ ){
if( data[i][2] == project ){
n++;// increment each time condition is true
body += "<tr><td style=" + STYLE.TD + ">" + data[i].join("</td><td style=" + STYLE.TD + ">") + "</td></tr>";
}
}
return [body,n];// return an array of 2 values
}
Usage :
var result = getGlobers(range,project);
Logger.log('array result = '+result);
Logger.log('body (string) = '+result[0]);
Logger.log('length (integer) = '+result[1]);
note : instead of an array you could also return an object with 2 properties... a matter of choice.
EDIT : an example using object properties :
function getGlobers(globers, project){
var body = "";
var n = 0;
var result = {};
var data = globers.getValues();
for( i = 0; i < data.length; i++ ){
if( data[i][2] == project ){
n++;
body += "<tr><td style=" + STYLE.TD + ">" + data[i].join("</td><td style=" + STYLE.TD + ">") + "</td></tr>";
}
}
result['body'] = body;
result['length'] = n;
return result;
}
Usage :
var result = getGlobers(range,project);
Logger.log('body = '+result.body);
Logger.log('length = '+result.length);

Sort JSON data by Date/Time value

Hope someone could help with this small task. I have an array of text blocks that have a DateTime value assigned to them. I would like to publish those text blocks sorted by DateTime so that the latest updated item is always on top.
Here is the script:
function jsonCallBack(data) {
var strRows = "";
$.each(data.News, function(i, item) {
var htmlNewsBody = item["htmlNewsBody"];
var maxLength = 120
var trimmedString = htmlNewsBody.substr(0, maxLength);
trimmedString = trimmedString.substr( 0, Math.min( trimmedString.length,
trimmedString.lastIndexOf(" ") ) );
strRows += "<div id='nrNewsItem-" + i + "'>";
strRows += "<h3>" + item["txtTitle"] + "</h3>";
strRows += "<p>" + item["dtDateTime"] + "</p>";
strRows += "<p>" + trimmedString + "...</p>";
strRows += "</div>"
});
$("#printHere").html(strRows);
};
Also have a working jsFiddle with JSON data.
You can add a custom compare method:
function compare(a,b) {
if (a.dtDateTime < b.dtDateTime) {
return 1;
}
if (a.dtDateTime > b.dtDateTime) {
return -1;
}
return 0;
}
Then in your function:
function jsonCallBack(data) {
data.News.sort(compare);
....

IE 8 - Invalid source HTML for this operation

What is wrong with
el.insertAdjacentHTML(hashVal[0], html);
where html is "<a title=\"\">1</a>" and hashVal[0] is "afterBegin".
This is related to a rating functionality. I think due to this error, the rating star is not displaying in ie 8. Other browsers are ok.
I have given the full flow of code below. I am using extjs.
var starLink = star.createChild({
tag: 'a',
html: this.values[i],
title: this.showTitles ? this.titles[i] : ''
});
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
createChild : function(config, insertBefore, returnDom) {
config = config || {tag:'div'};
if (insertBefore) {
return Ext.DomHelper.insertBefore(insertBefore, config, returnDom !== true);
}
else {
return Ext.DomHelper[!this.dom.firstChild ? 'insertFirst' : 'append'](this.dom, config, returnDom !== true);
}
},
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
insertFirst : function(el, o, returnElement){
return doInsert(el, o, returnElement, afterbegin, 'firstChild');
},
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function doInsert(el, o, returnElement, pos, sibling, append){
el = Ext.getDom(el);
var newNode;
if (pub.useDom) {
newNode = createDom(o, null);
if (append) {
el.appendChild(newNode);
} else {
(sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
}
} else {
newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
}
return returnElement ? Ext.get(newNode, true) : newNode;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function createHtml(o){
var b = '',
attr,
val,
key,
cn,
i;
if(typeof o == "string"){
b = o;
} else if (Ext.isArray(o)) {
for (i=0; i < o.length; i++) {
if(o[i]) {
b += createHtml(o[i]);
}
}
} else {
b += '<' + (o.tag = o.tag || 'div');
for (attr in o) {
val = o[attr];
if(!confRe.test(attr)){
if (typeof val == "object") {
b += ' ' + attr + '="';
for (key in val) {
b += key + ':' + val[key] + ';';
}
b += '"';
}else{
b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"';
}
}
}
if (emptyTags.test(o.tag)) {
b += '/>';
} else {
b += '>';
if ((cn = o.children || o.cn)) {
b += createHtml(cn);
} else if(o.html){
b += o.html;
}
b += '</' + o.tag + '>';
}
}
return b;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
insertHtml : function(where, el, html){
var hash = {},
hashVal,
range,
rangeEl,
setStart,
frag,
rs;
where = where.toLowerCase();
hash[beforebegin] = ['beforeBegin', 'previousSibling'];
hash[afterend] = ['afterEnd', 'nextSibling'];
if (el.insertAdjacentHTML) {
if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
return rs;
}
hash[afterbegin] = ['afterBegin', 'firstChild'];
hash[beforeend] = ['beforeEnd', 'lastChild'];
if ((hashVal = hash[where])) {
el.insertAdjacentHTML(hashVal[0], html);
return el[hashVal[1]];
}
} else {