Click here to Skip to main content
15,881,687 members
Please Sign up or sign in to vote.
1.00/5 (3 votes)
Friends,

I found in Http://www.roseindia.net/javascript/javascriptexamples/javascript-get-excel-file-data.shtml, a routine to access Excel data.

What I need is the same routine with adjusts.

The Excel data should be shown as follows: Hovering the mouse over the button the cell information must appear in tooltip next to the button.

Please, pay attention. I need a tooltip with excel data inside.


Thanks
Posted
Updated 19-Jul-12 16:54pm
v2

So what have you tried, where are you stuck?
Simply put, you need to call the function that's called for the button in order to retrieve the data. You then need to attach the data to the button in the form of a tool-tip.

To set an HTML object's tooltip, you just set it's title.

There's a number of interesting gotchas with the code you've linked to.

1) Will only work with IE (may possibly be achievable using the <object> tag along with the classID of excel, but ActiveX only works with IE.

2) Each time a button is pressed, a new instance of excel is started. You keep idle zombi-threads in the background since the code doesn't call excelApp.Quit()

3) If excel is set to Run As Administrator on the client pc, the code won't run unless the browser has also been run using admin privileges.


I'll also point out, that you're better off using excelApp as a global so you only have to start it once and you also have the opportunity to close it. The browser should close all activeX objects when it's closed, but it doesn't (IE8)


Anyway, here's some code that will create buttons on the fly, labelling them, setting their tool-tip and also setting a rudimentary onclick function. You can modify to suit your needs. Most notably by deciding whether or not to load the data again when the button is pressed, (need to call initExcel first, since I closed it in the init function) or whether to simply use the value that was loaded when the buttons were created.

You may wonder what's with the funny function notation inside the loop - that's called a closure and is there to make sure that each button's onclick function gets the right value for curVal. If you don't do it - all the buttons refer back to the same orignal variable which gets left holding the last value put into it during an execution of the loop.

HTML
<html>
<head>
<title>
Get data from excel sheet
</title>
<script language="javascript" >
var excelApp=null, excelFile=null, excelSheet=null;
var filename = "C:\\Users\\enhzflep\\Documents\\Book2.xlsx";

  function initExcel(filename)
  {
	excelApp = new ActiveXObject("Excel.Application");
	excelFile = excelApp.Workbooks.Open(filename);
	excelSheet = excelApp.Worksheets('Sheet1');
  }

  function myShutdownExcel()
  {
	excelApp.Quit();
	excelApp=null;
	excelFile=null;
	excelSheet=null;
  }
  
  function myGetData(column, row)
  {
	return excelSheet.Cells(column, row).Value;
  }
  
  function byId(e) {return document.getElementById(e);}
  
  function createButton(id, value, tooltip)
  {
	var btn = document.createElement('input');
	btn.setAttribute('type', 'button');
	btn.setAttribute('value', value);
	btn.setAttribute('id', id);
	btn.setAttribute('title', tooltip+"");
	btn.setAttribute('click', onclickfn);
	return btn;
  }
  function myOnLoad()
  {
	var btn, val, holder;
	var col=1, row=1;

	byId('filenameTgt').innerHTML = filename;
	
	holder = byId('controlHolder');
	initExcel(filename);

	for (row=1; row<=4; row++)
	{
		for (col=1; col<=4; col++)
		{
			(
				function()
				{
					var curVal;
					val = myGetData(row,col);
					
					curVal = val;
					btn = createButton('btn1', 
									   'Col('+col+'),Row('+row+')', 
									   'The value of cell['+col+','+row+']\nis: '+val);
					btn.onclick = function()
					{
						alert(curVal);
					}
					holder.appendChild(btn);
				}
			)();
		}
		holder.appendChild(document.createElement('br'));
	}
	myShutdownExcel();
}
  </script>
</head>
<body onload="myOnLoad();">
<p> </p>
<div style="background: #009955; width:'100%';" align="center">
  <font color="#000080" size="12pt">
<b>Get data from excel sheets</b>
  </font>
</div>
<center>
<p>&nbsp;</p>
<div id="div1" style="background: #DFDFFF; width:'100%';" align="center">
Click buttons to fetch data from <div id="filenameTgt"></div>
</div>
	<div id="controlHolder">
	</div>
</center>
</body>
</html>
 
Share this answer
 
v2
Comments
Sandeep Mewara 20-Jul-12 18:03pm    
My 5!
ZecaPOA 22-Jul-12 17:16pm    
friend,

I want to thank the time you lost trying to help me. I expected a simple code, I could understand. Unfortunately I do not understand your code and I'm giving up on finding a tooltip with data in Excel. I will start to see if I can find a pure Excel solution. I would not want to use it in excel, but as I find another way ... it will be anyway.

thank you
enhzflep 22-Jul-12 19:03pm    
It's a pleasure my friend. :)
I loose no time trying to help - I learn more while I trying to answer your question. Thanks & good luck. :)
ZecaPOA 31-Jul-12 11:08am    
Dear friend,
I returned to the initial project. I try to understand the code and test it. Here the buttons were not created. Apparently the code creates them, but do not come to me. Am I doing something wrong?
I tried to create them using the routine Roseindia and neither worked.
enhzflep 31-Jul-12 11:22am    
G'day Mate.
That sounds interesting - that the buttons were not created. Perhaps there is an error in your code, perhaps there is some other factor that prevents success coming to you.

Just so I am clear and understand you - did you try the code I pasted, with an appropriate value for filename?
Also, which version of Internet Explorer are you using?
Here you go - I hope it's what you're interested in. If not, let me know and I'll do the best I can. :)

HTML
<html>
<head>
<title>Get data from excel sheet</title>
<script language="javascript" >
var excelApp=null, excelFile=null, excelSheet=null;
var filename = "C:\\Users\\enhzflep\\Documents\\Book2.xlsx";

  function initExcel(filename)
  {
	excelApp = new ActiveXObject("Excel.Application");
	excelFile = excelApp.Workbooks.Open(filename);
	excelSheet = excelApp.Worksheets('Sheet1');
  }

  function myShutdownExcel()
  {
	excelApp.Quit();
	excelApp=null;
	excelFile=null;
	excelSheet=null;
  }
  
  function myGetData(column, row)
  {
	return excelSheet.Cells(column, row).Value;
  }
  
  function byId(e) {return document.getElementById(e);}
  
function myOnLoad2()
{
	var numRows = 5, numCols = 7;
	var tBody = byId('dataTableBody');
	var rowIndex, colIndex, curVal;
	var curRow, curCell, curCellText;
	initExcel(filename);
	
	for (rowIndex=1; rowIndex<=numRows; rowIndex++)
	{
		curRow = document.createElement('tr');
		for (colIndex=1; colIndex<=numCols; colIndex++)
		{
			curVal = myGetData(rowIndex, colIndex);
			curCell = document.createElement('td');
			curCell.setAttribute('title', 'The value of cell [' + rowIndex + ',' + colIndex +']\nis: ' + curVal);
			curCellText = document.createTextNode(curVal);
			curCell.appendChild(curCellText);
			curRow.appendChild(curCell);
		}
		tBody.appendChild(curRow);
	}
	myShutdownExcel();
}
</script>
<style>
table
{
	border: solid 1px #555;
}
td
{
	width: 32px;
	border: solid 1px #aaa;
}
</style>

</head>
<body onload="myOnLoad2();">
<b>Get data from excel sheets</b>
<table id='dataTable'>
 <tbody id='dataTableBody'>
 </tbody>
</table>
</body>
</html>


Output:
Actual output has borders around each cell, also has wider cells.
The tool-tips still work here though - try mousing over the table.
1234567
abcdefg
891011121314
hijklmn
15161718192021
 
Share this answer
 
Comments
ZecaPOA 31-Jul-12 18:03pm    
It's perfect. One more thing... if the cell in HTML table are col 1, row 1 and in excel are col 3 row 5. How I do?
enhzflep 31-Jul-12 18:24pm    
Excellent!
The tool-tips come from the excel col,row. So all you should have to do is
change the starting indexes in the for loops.

For example, say I only wanted the bottom-right 1/4 of the table I displayed above - all I would have to do is change the for loops to this:

for (rowIndex=5; rowIndex<=numRows; rowIndex++)
{
curRow = document.createElement('tr');
for (colIndex=3; colIndex<=numCols; colIndex++)
...
...

I will then get:

<TABLE id=dataTable><TBODY id=dataTableBody>
<TR>
<TD title="The value of cell [5,3]is: 17">17</TD>
<TD title="The value of cell [5,4]is: 18">18</TD>
<TD title="The value of cell [5,5]is: 19">19</TD>
<TD title="The value of cell [5,6]is: 20">20</TD>
<TD title="The value of cell [5,7]is: 21">21</TD></TR></TBODY></TABLE>

So, you just have to change the indexes used when calling myGetData.
ZecaPOA 31-Jul-12 18:33pm    
My friend,

You are fantastic. Tireless in seeking solutions. Congratulations for your dedication.

Now do not bother more. :)

Hug
enhzflep 31-Jul-12 18:47pm    
Grins and sticks out tongue!
Thank-you so very much..

If I'm ever in Brazil, I'll be sure to try to contact you Renato. My partner adores your country. And I'd really like to visit the 300m radio telescope too.

Cheers Mate!
ZecaPOA 2-Aug-12 10:57am    
Simon,

Here I go again ... I thought I could handle, but I realized that I'm really out of context. I was a programmer in the 90s and stopped for many years. Now I needed to return to this application I'm developing and every step I take I seem to carry an iron ball attached.

The help you gave me solved part of the situation, but a little more evolved level of difficulty increases.

For example: as soon as I started to build the application the idea was to have mounted a table in HTML that was associated with an Excel spreadsheet.

I would see the price of each apartment (I work in real estate) that are in the excel spreadsheet to hover over the items in the HTML table.

Your help creating the HTML table directly from Excel was excellent, but some situations do not apply.

Let me now explain the problem. I have to visually show the excel table with colors. The apartments are sold in blue, reserved orange and white available for sale.

So I had thought of first creating a table in HTML manually assigning colors to each "cell" and then assign the address of the cell to excel.

This is the first problem. The second is that I can submit more than one table on screen at once. There are cases where I have 7 tables being displayed on the screen (7 buildings with apartments).

Due to the complexity here I started to create multiple tables and accesses crazy and I do not think it was good and not efficient.

Can you help me again? Feel comfortable to refuse because I understand that I am abusing their knowledge, but as you were the one to answer me ...
Renato, no worries mate. It's been some interesting learning for me..

I've re-written the source to make it neater, clearer and more functional.
I've made a new function that reads in a specified excel file, copying the data in the desired cells into a html table. The cell colours are copied from the spreadsheet.

You may reference the same file multiple times, you may reference several files.
Each call to the function returns a new table.

The code is still fairly generalized - you may want to alter the logic if you are reading from several different sections of the same file - at the moment, each call to the function
  • starts excel
  • opens the specified file
  • reads the data
  • quits excel


It does seem rather slow - I suspect that it's just the interaction between javascript and the COM object - you could try to read a large section of data from 1 file to gague the effect of (a) regular operations (b) initializing/quiting excel.

Hope it's useful! :)

Code:
HTML
<html>
<head>
<title>Get data from excel sheet(s)</title>
<script language="javascript" >
var excelApp=null, excelFile=null, excelSheet=null;

  function initExcel(filename)
  {
	excelApp = new ActiveXObject("Excel.Application");
	excelFile = excelApp.Workbooks.Open(filename);
	excelSheet = excelApp.Worksheets('Sheet1');
  }

  function myShutdownExcel()
  {
	excelApp.Quit();
	excelApp=null;
	excelFile=null;
	excelSheet=null;
  }
  
  function myGetData(column, row)
  {
	return excelSheet.Cells(column, row).Value;
  }
  
  function myGetCellColor(column, row)
  {
	return excelSheet.Cells(column, row).Interior.Color;
  }
  
  function byId(e) {return document.getElementById(e);}
  
  
// takes a 24 bit number that represents a colour in excel
//	Excel represents colours an int. When displayed in hex, the fmt is BBGGRR 
//	Html represents colours as RRGGBB
function excelToHtmlColor(decNum)
{
	var hexStrVal, r, g, b

	// get a hexidecimal string representation of the number
	hexStrVal = decNum.toString(16);
	
	// pad to 6 bytes long
	while (hexStrVal.length < 6)
	{
		hexStrVal = "0" + hexStrVal; //hexStrVal += "0";
	}
	
	// extract the 3 components
	r = hexStrVal.substr(4,2);
	g = hexStrVal.substr(2,2);
	b = hexStrVal.substr(0,2);
	
	// return them in reverse order
	return r+g+b;
}


// reads an excel file
//	- creates a table using all cells between and including those specified
//  - copies the colour of the excel cell to the html cell's style.backgroundColor attribute
// Note: the order of the args - excel notation is Row,Col (y,x)  - while we use Col,Row (x,y)
function createTableFromExcel(excelFilename, tableId, firstCol,firstRow, lastCol,lastRow)
{
	var table, tbody, tRow, tCell;
	var curRow, curCol;
	
	initExcel(excelFilename);
	table = document.createElement('table');
	table.setAttribute('id', tableId);
	
	tbody = document.createElement('tbody');
	table.appendChild(tbody);
	
	for (curRow=firstRow; curRow<=lastRow; curRow++)
	{
		tRow = document.createElement('tr');
		for (curCol=firstCol; curCol<=lastCol; curCol++)
		{
			// create a td element
			tCell = document.createElement('td');
			
			// grab the color and value of the excel cell
			curVal = myGetData(curRow, curCol);
			if (curVal==undefined)
				curVal = " ";
			curColor = myGetCellColor(curRow, curCol);
			
			// set the style of this cell such that it's background is the same color as the excel cell it corresponds to
			curColorStr = "#" + excelToHtmlColor(curColor);
			tCell.style.backgroundColor = curColorStr;

			// set the text of the cell
			cellText = document.createTextNode(curVal);
			tCell.appendChild(cellText);
		
			tRow.appendChild(tCell);
		}
		tbody.appendChild(tRow);
	}
	myShutdownExcel();
	return table;
}
  
function mOnLoadFunc()
{
	var filename1 = "C:\\Users\\enhzflep\\Documents\\Book2.xlsm";
	var parent = byId('tableHolder');

	var child = createTableFromExcel(filename1, 'table1', 1,1, 7,11);
	parent.appendChild(child);
	parent.appendChild(document.createElement('br'));
	
	child = createTableFromExcel(filename1, 'table2', 1,7, 3,11);
	parent.appendChild(child);
	parent.appendChild(document.createElement('br'));

	child = createTableFromExcel(filename1, 'table3', 4,7, 4,11);
	parent.appendChild(child);
	parent.appendChild(document.createElement('br'));

	child = createTableFromExcel(filename1, 'table4', 5,7, 7,11);
	parent.appendChild(child);
}
</script>
<style>
table
{
	border: solid 1px #555;
}
td
{
	width: 32px;
	border: solid 1px #aaa;
	height: 16px;
}
</style>

</head>
<body onload="mOnLoadFunc();">
<b>Get data from excel sheets</b>
<div id="tableHolder"></div>
</body>
</html>


Result:


BCDEFG
2bcdefg
391011121314
4ijklmn
5161718192021
6
7BCDEFG
81312111098
9IJKLMN
10654321
11PQRSTU



7BC
81312
9IJ
1065
11PQ



D
11
K
4
R



EFG
1098
LMN
321
STU



 
Share this answer
 
Comments
ZecaPOA 2-Aug-12 18:05pm    
The code you wrote to contemplate the situation where I had told him.

The issue is that sheet excel comes from the financial area and I am the sales area. The sheet data that comes from the financial information does not have colors. Is the sales staff that puts the colors in the cells.

Hence we use HTML to view the developments.

Another question: each project has its own spreadsheet, where are the buildings (1 or more).

What worries me in this new scenario is to have the independence that would provide me HTML, where I could change colors all the time without interfering with the financial worksheet data.

I remembered that early in the design I had sketched a screen where I put HTML excel data manually into the HTML header of each cell. It worked and gave the highest job.

Then I start looking for the integration of HTML table that I had with the tooltip with the data from excel.

Your suggestions were great and either automated the creation of the HTML table and assigns to each cell HTML its due EXCEL table, but is seems to me that the difficulty I have to manipulate the HTML details I have to get back the initial idea.

I wanted to attach the initial model I wrote, but have not found where he could do it. Do not want to publicly display the code as it is immensely primitive compared to his. If you have any way to get my file would indicate.

Accept other suggestions if you have.

Hug
enhzflep 2-Aug-12 23:44pm    
Just woken up recently. Still half asleep. Please, by all means feel free to email the hand-made table &/or JS code. Will make things easier..

I have yahoo (dot com dot AU) account - username is same as username here.
Or you can find a regular post (I.e not QA answer) of mine and click the Email button on bottom of it this will give me your email, I can reply to that, you can send attachment back to that addr. :thumbs-up:

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900