Python Library Or Code To Read Already Open Excel File
Solution 1:
I am not 100% sure if this solution works with DDE (is the file being written to disk somewhere?)
I recommend using xlrd
(https://github.com/python-excel/xlrd). I personally installed it via pip. Then to simply read A1:B3 do as such (ripped off the docs):
from xlrd import open_workbook
wb = open_workbook('spreadsheet.xlsx')
for s in wb.sheets():
print('Sheet:',s.name) # you can checkfor the sheet name here if you want
forrowinrange(2): #the first2rows (A and B) (use s.nrows forall)
values= []
for col inrange(3): #the first3 columns (use s.ncols forall)
values.append(str(s.cell(row,col).value))
print(','.join(values))
Solution 2:
I needed exactly the same solution and here is what I did (it's already working):
I created a local http server and an local websocket server on different ports (8080 and 3000) with Node.js (using Node Webkit, but you can use pure Node.js).
On http server I set http://localhost:8080/write/ to receive a GET request with the params I wanted and to broadcast a message to the websocket server with those params.
I wrote a VBA code to push data to the local http server, using Worksheet_Calculate sub (it's an event fired every time the worksheet refresh its content).
Finnaly I made Python to listen to the websocket server (ws://localhost:3000/), waiting for the server signal.
Diving into coding details:
To create local server I used Express and ws modules. The first one to create http server and the second to create websocket server:
Express details:
var express = require('express');
var app = express();
app.get('/', function (req, res) { res.send('Hello World!') }) // to see if server is on// broadcast data on q GET variable: http://localhost:8080/write/?q=32,34,23
app.get('/write/', function (req, res) {
wss.broadcast(req.query.q); // this line uses the variable created below
res.send();
});
var server = app.listen(8080, function () {});
ws details:
var WebSocketServer = require('ws').Server;
wss = new WebSocketServer({port: 3000});
wss.on('connection', function(ws) {
// you can use this event to perform some action when python get connected
ws.send("you're connected");
// use this event if you need websocket to receive message
ws.on('message', function(message) {
ws.send(message);
});
});
wss.broadcast = functionbroadcast(data) {
wss.clients.forEach(functioneach(client) {
client.send(data);
});
};
To send data from Excel to the http server (I tried to use websocket, but I couldn't figure out how Excel connects to a websocket):
Function postServer(url, data)
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
objHTTP.Open "GET", url & data, False' true para asynchronous calls
objHTTP.send '(dados)
postServer = 1'It's a good idea to get the responseHTML from server and verifies if the everything is all rightEndFunction
Use this function inside Worksheet_Calculate() to send data:
PrivateSub Worksheet_Calculate()
server = "http://localhost:8080/write/?q="'data = <something> 'catch your data with vba code
postServer(server,data)
Endsub
The trick detail here is how to know when some data is already sent so you can avoid send it twice or more. You'll have to create your method based on how your data is organized on the sheet. For me, a have a number column, ordered and a cell registering the last number I sent.
Ok! Now you have to prepare Python to receive this data:
I downloaded the websocket-client 0.25.0 module. And here is the python code to listen to the websocket server:
import sys
import websocket
import thread
import time
wsAddress = "ws://localhost:3000/"defon_message(ws, message):
print message # you got it!defon_error(ws, error):
print error
defon_close(ws):
print"### closed ###"defon_open(ws):
print"conectado"if __name__ == "__main__":
websocket.enableTrace(True)
ws = websocket.WebSocketApp(wsAddress,
on_message = on_message,
on_error = on_error,
on_close = on_close)
ws.on_open = on_open
ws.run_forever()
If you're on a local network, you can use IP (or machine names) to post and listen to the server (it's awesome). Here is the code to discover the id with node.js:
var os = require('os');
var ifaces=os.networkInterfaces();
for (var dev in ifaces) {
var alias=0;
ifaces[dev].forEach(function(details){
if ((details.family=='IPv4')&&(details.address!="127.0.0.1")&&(details.internal === false)) {
console.log(details.address);
++alias;
}
});
}
I hope I've helped. If you let some questions, just let me know.
Solution 3:
I wanted to share a solution largely stolen from this StackOverflow solution since I've found xlrd to have inconsistent outcomes when opening Excel files that may or may not be opened by another user on the network. Using win32com has (so far) worked better for me.
#using path to avoid escape character errorsfrom pathlib import Path
path = Path(r'/full/filepath')
from win32com import client
xlApp = client.GetObject(None, "Excel.Application")
books = xlApp.Workbooks.Open(path)
ws = books.Worksheets[0]
ws.Visible = 1#returns tuple
shift_1 = ws.Range("A1:B2").Value
import numpy as np
#selection of 0 element of tuple would depend on use case.
shift_1 = np.asarray(shift_1[0])
Post a Comment for "Python Library Or Code To Read Already Open Excel File"