假设我已经打开了一个Excel 2013文件(例如XYZ.xlsx) - 该文件通过DDE链接获取一些数据。假设我想从工作表中读取某些单元格(比如A1:B3)(比如Sheet1)。我怎么能在Python 3中完成它(我使用的是Python 3.4.2.4 / Winpython安装)?
我找到了openpyxl
包,但我无法理解如何让它读取活动的打开工作簿?
答案 0 :(得分:2)
我不能100%确定此解决方案是否适用于DDE(文件是否正在某处写入磁盘?)
我建议使用xlrd
(https://github.com/python-excel/xlrd)。我个人通过pip安装它。然后简单地阅读A1:B3这样做(扯掉文档):
from xlrd import open_workbook
wb = open_workbook('spreadsheet.xlsx')
for s in wb.sheets():
print('Sheet:',s.name) # you can check for the sheet name here if you want
for row in range(2): #the first 2 rows (A and B) (use s.nrows for all)
values = []
for col in range(3): #the first 3 columns (use s.ncols for all)
values.append(str(s.cell(row,col).value))
print(','.join(values))
答案 1 :(得分:1)
我需要完全相同的解决方案,这就是我所做的(它已经在工作):
我使用Node.js在不同的端口(8080和3000)上创建了本地http服务器和本地websocket服务器(使用Node Webkit,但您可以使用纯Node.js)。
在http服务器上,我设置http://localhost:8080/write/以接收带有我想要的参数的GET请求,并使用这些参数向websocket服务器广播消息。
我编写了一个VBA代码,使用Worksheet_Calculate sub将数据推送到本地http服务器(这是每次工作表刷新其内容时触发的事件)。
Finnaly我让Python听取websocket服务器(ws:// localhost:3000 /),等待服务器信号。
要创建本地服务器,我使用了Express和ws模块。第一个创建http服务器,第二个创建websocket服务器:
快递详情:
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 () {});
详情:
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 = function broadcast(data) {
wss.clients.forEach(function each(client) {
client.send(data);
});
};
将数据从Excel发送到http服务器(我尝试使用websocket,但我无法弄清楚Excel如何连接到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 right
End Function
在Worksheet_Calculate()中使用此函数发送数据:
Private Sub Worksheet_Calculate()
server = "http://localhost:8080/write/?q="
'data = <something> 'catch your data with vba code
postServer(server,data)
End sub
这里的技巧细节是如何知道某些数据何时已经发送,因此您可以避免两次或更多次发送。您必须根据工作表中数据的组织方式创建方法。对我来说,有一个数字列,有序,一个单元格注册我发送的最后一个数字。
确定!现在你必须准备Python来接收这些数据:
我下载了websocket-client 0.25.0模块。这是用于监听websocket服务器的python代码:
import sys
import websocket
import thread
import time
wsAddress = "ws://localhost:3000/"
def on_message(ws, message):
print message # you got it!
def on_error(ws, error):
print error
def on_close(ws):
print "### closed ###"
def on_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()
如果您在本地网络上,则可以使用IP(或计算机名称)发布和收听服务器(这很棒)。以下是使用node.js发现id的代码:
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;
}
});
}
我希望我能帮到你。如果你有些问题,请告诉我。
答案 2 :(得分:0)
我想分享一个在此StackOverflow solution上失窃的解决方案,因为我发现xlrd在打开可能由网络上的另一个用户打开或不能打开的Excel文件时结果不一致。到目前为止,使用win32com对我来说效果更好。
#using path to avoid escape character errors
from 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])