python库或代码读取已打开的Excel文件

时间:2015-02-06 01:10:54

标签: python excel python-3.x

假设我已经打开了一个Excel 2013文件(例如XYZ.xlsx) - 该文件通过DDE链接获取一些数据。假设我想从工作表中读取某些单元格(比如A1:B3)(比如Sheet1)。我怎么能在Python 3中完成它(我使用的是Python 3.4.2.4 / Winpython安装)?

我找到了openpyxl包,但我无法理解如何让它读取活动的打开工作簿?

3 个答案:

答案 0 :(得分:2)

我不能100%确定此解决方案是否适用于DDE(文件是否正在某处写入磁盘?)

我建议使用xlrdhttps://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)

我需要完全相同的解决方案,这就是我所做的(它已经在工作):

  1. 我使用Node.js在不同的端口(8080和3000)上创建了本地http服务器和本地websocket服务器(使用Node Webkit,但您可以使用纯Node.js)。

  2. 在http服务器上,我设置http://localhost:8080/write/以接收带有我想要的参数的GET请求,并使用这些参数向websocket服务器广播消息。

  3. 我编写了一个VBA代码,使用Worksheet_Calculate sub将数据推送到本地http服务器(这是每次工作表刷新其内容时触发的事件)。

  4. Finnaly我让Python听取websocket服务器(ws:// localhost:3000 /),等待服务器信号。


  5. 潜入编码细节:

    要创建本地服务器,我使用了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])