我正在尝试阅读libreoffice计算电子表格,使用ezodf和python 3更新特定表格上的值。由于我们是多平台(FreeBSD,Linux,OSX,pi),我们正在尝试将此过程转换为使用ods
以json格式从另一台主机检索数据并将其写入相应的libreoffice工作表/单元格(以下摘录代码下面的缩写说明):
def iso_watch():
# Open Master coord sheets
doc = ezodf.opendoc(_COORD_MASTER_SPREADSHEET_TEST_URI)
sheet = doc.sheets['isocenter_delta']
# Now fetch the isocenters and display them in the table.
no_rows = sheet.nrows()
iso_list = []
iso__value = []
ddx = []
for index in range(0, no_rows):
row = sheet.row(index)
ddx.append(ss())
# get isocenter and present value from mss (master spreadsheet)
iso = is_none(row[0].value)
iso_delta = is_none(row[1].value)
ddx[index].iso = iso
ddx[index].delta = iso_delta
ddx[index].loc = index
if row[0].value != None:
iso_list.append(iso)
iso_value.append(iso_delta)
url = _PI_DATA_ACQIF_ARDUINO
r = requests.get(url, headers=_ISOSLAVE_headers)
if r.status_code != 200:
print("Bad request: status:",r.status_code, r.url)
ddx[index].new_value = iso_value
continue
rj = r.json()
if rj:
try:
ddx[index].new_value = rj[0]['LastIso']
sheet[index,1].set_value(ddx[index].new_value, 'float')
except KeyError:
print(r.status_code, iso.upper(), "Couldn't get the iso record")
ddx[index].new_value = iso_value # keep old value -- don't update a bad iso delta
continue
except IndexError:
print(r.status_code, r.url, "Badness here: Index Error")
continue
else:
print("RJ has NO stuff.", r.url, index, "Keeping Backup Data" )
ddx[index].new_value = iso_delta #keep old data
# At this point we have a list of present isocenter shifts and their values. We have displayed the old ones on the form.
# We are now going to open a brand new shiny spreadsheet and write the values on the fresh sheet.
# If this works, we will try a real run against a copy of the production sheet. (it worked...so see if rj code above)
ods = newdoc(doctype ='ods', filename='/Users/brtc/sw/fl_mf/pvt/test.ods')
ods.sheets += Sheet('Sheet1')
mysheet = ods.sheets[0]
mysheet.append_rows(150)
print ('Index ', ods.docname, len(ddx), mysheet.name, doc.sheets[0].name)
# label it
mysheet[2,0].set_value('Isocenter')
mysheet[2,1].set_value('Present Delta')
mysheet[2,2].set_value('Old Delta')
mysheet[2,3].set_value('Shift Vector')
for index in range (3, no_rows):
if ddx[index].ticker != 0:
tt = ddx[index].iso
pp = Decimal(ddx[index].value)
nv = Decimal(ddx[index].new_value)
mysheet[index, 0].set_value(tt)
mysheet[index, 2].set_value(pp)
mysheet[index, 1].set_value(nv)
print('***Debug*** tt pp nv',tt, pp, ddx[index].value, nv, ddx[index].new_value )
print('posting ', mysheet[index, 0].value, mysheet[index, 1].value, mysheet[index, 2].value)
else:
print('***DEBUG*** ISO is zero, set tt to blank ' )
tt = ' '
pp = ''
nv = ''
print('posting ', mysheet[index,0].value, mysheet[index,1].value, mysheet[index,2].value)
ods.save()
doc.save()
return render_template('value_query.html', values=sheet, ivl = ddx, updatetime=time.asctime(time.localtime(time.time())))
print ('Completed @', time.asctime(time.localtime(time.time())))
归结为: 从json十进制数字xx.yyyy中的数据收集器(raspberry pi)上运行的webserver获取 以json元素返回 替换现有电子表格单元格中的十进制数。
到目前为止,上面的代码就是这样做的。问题是当在LO 5.x中打开电子表格时,数字在正确的位置出现并正确格式化,但是......它们没有做任何事情。我的意思是数字看起来是正确的,但引用这些单元格中的数字进行计算的单元格不会更新。让它更新的唯一方法是选择列副本并在列中粘贴相同的数据。然后整个ss正确更新。
例如:
ISO New Ref Old Ref Diff
Calib1 4.323 4.320 0.003
Calib2 5.175 5.000 0.175
检索数据并在工作表中替换时,会发生以下情况:
ISO New Ref Old Ref Diff
Calib1 4.323 4.320 0.000
Calib2 5.175 5.000 0.000
但是当我复制“New Ref”列,然后立即粘贴到列上时,它就像编程一样工作。进来的数据是
rj = r.json()
new_ref = rj[0]['new_ref']
并显示为固定的十进制数字。
print(rj[0]['new_ref'])
4.323
我怀疑ezodf没有正确设置ods单元格值类型,复制/粘贴会在libreoffice中重置它。我不依赖ezodf,但希望避免在我们的数据采集运行期间加载/运行libreoffice的开销。我没有拆开ods xml代码...但是,我很接近。