Skip to content

Commit 92be493

Browse files
committed
Merge pull request #58 from stephenlewis/feature-cell-comments-in-xlsx
Read cell comments in .xlsx files
2 parents e9ea2da + 53a872b commit 92be493

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

tests/test_comments_excel.xlsx

15.4 KB
Binary file not shown.

tests/test_comments_gdocs.xlsx

4.09 KB
Binary file not shown.

tests/test_xlsx_comments.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from unittest import TestCase
2+
3+
import os
4+
5+
from xlrd import open_workbook
6+
7+
from .base import from_this_dir
8+
9+
class TestXlsxComments(TestCase):
10+
11+
def test_excel_comments(self):
12+
book = open_workbook(from_this_dir('test_comments_excel.xlsx'))
13+
sheet = book.sheet_by_index(0)
14+
15+
note_map = sheet.cell_note_map
16+
self.assertEqual(len(note_map), 1)
17+
self.assertEqual(note_map[(0, 1)].text, 'hello')
18+
19+
def test_excel_comments_multiline(self):
20+
book = open_workbook(from_this_dir('test_comments_excel.xlsx'))
21+
sheet = book.sheet_by_index(1)
22+
23+
note_map = sheet.cell_note_map
24+
self.assertEqual(note_map[(1, 2)].text, '1st line\n2nd line')
25+
26+
def test_excel_comments_two_t_elements(self):
27+
book = open_workbook(from_this_dir('test_comments_excel.xlsx'))
28+
sheet = book.sheet_by_index(2)
29+
30+
note_map = sheet.cell_note_map
31+
self.assertEqual(note_map[(0, 0)].text, 'Author:\nTwo t elements')
32+
33+
def test_excel_comments_no_t_elements(self):
34+
book = open_workbook(from_this_dir('test_comments_excel.xlsx'))
35+
sheet = book.sheet_by_index(3)
36+
37+
note_map = sheet.cell_note_map
38+
self.assertEqual(note_map[(0,0)].text, '')
39+
40+
def test_gdocs_comments(self):
41+
book = open_workbook(from_this_dir('test_comments_gdocs.xlsx'))
42+
sheet = book.sheet_by_index(0)
43+
44+
note_map = sheet.cell_note_map
45+
self.assertEqual(len(note_map), 1)
46+
self.assertEqual(note_map[(0, 1)].text, 'Just a test')

xlrd/xlsx.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,31 @@ def own_process_stream(self, stream, heading=None):
532532
elif elem.tag == U_SSML12 + "mergeCell":
533533
self.do_merge_cell(elem)
534534
self.finish_off()
535-
535+
536+
def process_comments_stream(self, stream):
537+
root = ET.parse(stream).getroot()
538+
author_list = root[0]
539+
assert author_list.tag == U_SSML12 + 'authors'
540+
authors = [elem.text for elem in author_list]
541+
comment_list = root[1]
542+
assert comment_list.tag == U_SSML12 + 'commentList'
543+
cell_note_map = self.sheet.cell_note_map
544+
from .sheet import Note
545+
text_tag = U_SSML12 + 'text'
546+
r_tag = U_SSML12 + 'r'
547+
t_tag = U_SSML12 + 't'
548+
for elem in comment_list.findall(U_SSML12 + 'comment'):
549+
ts = elem.findall('./' + text_tag + '/' + t_tag)
550+
ts += elem.findall('./' + text_tag + '/' + r_tag + '/' + t_tag)
551+
ref = elem.get('ref')
552+
note = Note()
553+
note.author = authors[int(elem.get('authorId'))]
554+
note.rowx, note.colx = coords = cell_name_to_rowx_colx(ref)
555+
note.text = ''
556+
for t in ts:
557+
note.text += cooked_text(self, t)
558+
cell_note_map[coords] = note
559+
536560
def do_dimension(self, elem):
537561
ref = elem.get('ref') # example: "A1:Z99" or just "A1"
538562
if ref:
@@ -766,6 +790,12 @@ def open_workbook_2007_xml(
766790
heading = "Sheet %r (sheetx=%d) from %r" % (sheet.name, sheetx, fname)
767791
x12sheet.process_stream(zflo, heading)
768792
del zflo
793+
comments_fname = 'xl/comments%d.xml' % (sheetx + 1)
794+
if comments_fname in component_names:
795+
comments_stream = getzflo(zf, comments_fname)
796+
x12sheet.process_comments_stream(comments_stream)
797+
del comments_stream
798+
769799
sheet.tidy_dimensions()
770800

771801
return bk

0 commit comments

Comments
 (0)