def test_parse_dxfs():
    reference_file = os.path.join(DATADIR, 'reader', 'conditional-formatting.xlsx')
    wb = load_workbook(reference_file)
    archive = ZipFile(reference_file, 'r', ZIP_DEFLATED)
    read_xml = archive.read(ARC_STYLE)

    # Verify length
    assert '<dxfs count="164">' in str(read_xml)
    assert len(wb.style_properties['dxf_list']) == 164

    # Verify first dxf style
    reference_file = os.path.join(DATADIR, 'writer', 'expected', 'dxf_style.xml')
    with open(reference_file) as expected:
        diff = compare_xml(read_xml, expected.read())
        assert diff is None, diff

    cond_styles = wb.style_properties['dxf_list'][0]
    assert cond_styles['font']['color'] == Color('FF9C0006')
    assert cond_styles['font']['bold'] == False
    assert cond_styles['font']['italic'] == False
    f = Fill()
    f.end_color = Color('FFFFC7CE')
    assert cond_styles['fill'][0] == f

    # Verify that the dxf styles stay the same when they're written and read back in.
    w = StyleWriter(wb)
    w._write_dxfs()
    write_xml = get_xml(w._root)
    read_style_prop = read_style_table(write_xml)
    assert len(read_style_prop['dxf_list']) == len(wb.style_properties['dxf_list'])
    for i, dxf in enumerate(read_style_prop['dxf_list']):
        assert repr(wb.style_properties['dxf_list'][i] == dxf)
Beispiel #2
0
    def test_nb_style(self):
        for i in range(1, 6):
            self.worksheet.cell(row=1, column=i).style.font.size += i
        w = StyleWriter(self.workbook)
        assert len(w.style_table) == 5

        self.worksheet.cell('A10').style.borders.top = Border.BORDER_THIN
        w = StyleWriter(self.workbook)
        assert len(w.style_table) == 6
Beispiel #3
0
 def test_fonts(self):
     self.worksheet.cell('A1').style.font.size = 12
     self.worksheet.cell('A1').style.font.bold = True
     w = StyleWriter(self.workbook)
     w._write_fonts()
     expected = """<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fonts count="2"><font><sz val="11" /><color theme="1" /><name val="Calibri" /><family val="2" /><scheme val="minor" /></font><font><sz val="12" /><color rgb="FF000000" /><name val="Calibri" /><family val="2" /><b /></font></fonts></styleSheet>"""
     xml = get_xml(w._root)
     diff = compare_xml(xml, expected)
     assert diff is None, diff
Beispiel #4
0
 def test_alignment(self):
     self.worksheet.cell('A1').style.alignment.horizontal = 'center'
     self.worksheet.cell('A1').style.alignment.vertical = 'center'
     w = StyleWriter(self.workbook)
     nft = w._write_number_formats()
     w._write_cell_xfs(nft, {}, {}, {})
     xml = get_xml(w._root)
     assert 'applyAlignment="1"' in xml
     assert 'horizontal="center"' in xml
     assert 'vertical="center"' in xml
Beispiel #5
0
 def test_fills(self):
     self.worksheet.cell('A1').style.fill.fill_type = 'solid'
     self.worksheet.cell(
         'A1').style.fill.start_color.index = Color.DARKYELLOW
     w = StyleWriter(self.workbook)
     w._write_fills()
     expected = """<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fills count="3"><fill><patternFill patternType="none" /></fill><fill><patternFill patternType="gray125" /></fill><fill><patternFill patternType="solid"><fgColor rgb="FF808000" /></patternFill></fill></fills></styleSheet>"""
     xml = get_xml(w._root)
     diff = compare_xml(xml, expected)
     assert diff is None, diff
Beispiel #6
0
 def test_borders(self):
     self.worksheet.cell(
         'A1').style.borders.top.border_style = Border.BORDER_THIN
     self.worksheet.cell(
         'A1').style.borders.top.color.index = Color.DARKYELLOW
     w = StyleWriter(self.workbook)
     w._write_borders()
     expected = """<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><borders count="2"><border><left /><right /><top /><bottom /><diagonal /></border><border><left /><right /><top style="thin"><color rgb="FF808000" /></top><bottom /><diagonal /></border></borders></styleSheet>"""
     xml = get_xml(w._root)
     diff = compare_xml(xml, expected)
     assert diff is None, diff
Beispiel #7
0
 def test_alignment_rotation(self):
     self.worksheet.cell('A1').style.alignment.vertical = 'center'
     self.worksheet.cell('A1').style.alignment.text_rotation = 90
     self.worksheet.cell('A2').style.alignment.vertical = 'center'
     self.worksheet.cell('A2').style.alignment.text_rotation = 135
     self.worksheet.cell('A3').style.alignment.text_rotation = -34
     w = StyleWriter(self.workbook)
     nft = w._write_number_formats()
     w._write_cell_xfs(nft, {}, {}, {})
     xml = get_xml(w._root)
     assert 'textRotation="90"' in xml
     assert 'textRotation="135"' in xml
     assert 'textRotation="124"' in xml
Beispiel #8
0
 def test_alignment_indent(self):
     self.worksheet.cell('A1').style.alignment.indent = 1
     self.worksheet.cell('A2').style.alignment.indent = 4
     self.worksheet.cell('A3').style.alignment.indent = 0
     self.worksheet.cell('A3').style.alignment.indent = -1
     w = StyleWriter(self.workbook)
     nft = w._write_number_formats()
     w._write_cell_xfs(nft, {}, {}, {})
     xml = get_xml(w._root)
     assert 'indent="1"' in xml
     assert 'indent="4"' in xml
     #Indents not greater than zero are ignored when writing
     assert 'indent="0"' not in xml
     assert 'indent="-1"' not in xml
Beispiel #9
0
def test_write_style():
    wb = Workbook()
    ws = wb.create_sheet()
    ws.cell('F1').value = '13%'
    ws.column_dimensions['F'].style_index = ws._styles['F1']
    style_id_by_hash = StyleWriter(wb).get_style_by_hash()
    content = write_worksheet(ws, {}, style_id_by_hash)
    reference_file = os.path.join(DATADIR, 'writer', 'expected',
                                  'sheet1_style.xml')
    with open(reference_file) as expected:
        diff = compare_xml(content, expected.read())
        assert diff is None, diff
Beispiel #10
0
 def setup_class(cls):
     now = datetime.datetime.now()
     cls.workbook = Workbook()
     cls.worksheet = cls.workbook.create_sheet()
     cls.worksheet.cell(coordinate='A1').value = '12.34%'
     cls.worksheet.cell(coordinate='B4').value = now
     cls.worksheet.cell(coordinate='B5').value = now
     cls.worksheet.cell(coordinate='C14').value = 'This is a test'
     cls.worksheet.cell(coordinate='D9').value = '31.31415'
     cls.worksheet.cell(
         coordinate='D9'
     ).style.number_format.format_code = NumberFormat.FORMAT_NUMBER_00
     cls.writer = StyleWriter(cls.workbook)
Beispiel #11
0
 def test_write_cell_xfs_1(self):
     self.worksheet.cell('A1').style.font.size = 12
     w = StyleWriter(self.workbook)
     ft = w._write_fonts()
     nft = w._write_number_formats()
     w._write_cell_xfs(nft, ft, {}, {})
     xml = get_xml(w._root)
     assert 'applyFont="1"' in xml
     assert 'applyFill="1"' not in xml
     assert 'applyBorder="1"' not in xml
     assert 'applyAlignment="1"' not in xml
Beispiel #12
0
 def test_style_unicity(self):
     for i in range(1, 6):
         self.worksheet.cell(row=1, column=i).style.font.bold = True
     w = StyleWriter(self.workbook)
     assert len(w.style_table) == 1
Beispiel #13
0
 def test_no_style(self):
     w = StyleWriter(self.workbook)
     assert len(w.style_table) == 0
Beispiel #14
0
 def __init__(self, workbook):
     self.workbook = workbook
     self.style_writer = StyleWriter(self.workbook)
Beispiel #15
0
class ExcelWriter(object):
    """Write a workbook object to an Excel file."""

    def __init__(self, workbook):
        self.workbook = workbook
        self.style_writer = StyleWriter(self.workbook)

    def write_data(self, archive):
        """Write the various xml files into the zip archive."""
        # cleanup all worksheets
        shared_string_table = self._write_string_table(archive)

        archive.writestr(ARC_CONTENT_TYPES, write_content_types(self.workbook))
        archive.writestr(ARC_ROOT_RELS, write_root_rels(self.workbook))
        archive.writestr(ARC_WORKBOOK_RELS, write_workbook_rels(self.workbook))
        archive.writestr(ARC_APP, write_properties_app(self.workbook))
        archive.writestr(ARC_CORE, write_properties_core(self.workbook.properties))
        if self.workbook.loaded_theme:
            archive.writestr(ARC_THEME, self.workbook.loaded_theme)
        else:
            archive.writestr(ARC_THEME, write_theme())
        archive.writestr(ARC_STYLE, self.style_writer.write_table())
        archive.writestr(ARC_WORKBOOK, write_workbook(self.workbook))

        if self.workbook.vba_archive:
            vba_archive = self.workbook.vba_archive
            for name in vba_archive.namelist():
                for s in ARC_VBA:
                    if name.startswith(s):
                        archive.writestr(name, vba_archive.read(name))
                        break

        self._write_worksheets(archive, shared_string_table, self.style_writer)

    def _write_string_table(self, archive):

        for ws in self.workbook.worksheets:
            ws.garbage_collect()
        shared_string_table = create_string_table(self.workbook)
        archive.writestr(ARC_SHARED_STRINGS,
                write_string_table(shared_string_table))

        return shared_string_table

    def _write_images(self, images, archive, image_id):
        for img in images:
            buf = BytesIO()
            img.image.save(buf, format= 'PNG')
            archive.writestr(PACKAGE_IMAGES + '/image%d.png' % image_id, buf.getvalue())
            image_id += 1
        return image_id

    def _write_worksheets(self, archive, shared_string_table, style_writer):
        drawing_id = 1
        chart_id = 1
        image_id = 1
        shape_id = 1
        comments_id = 1

        for i, sheet in enumerate(self.workbook.worksheets):
            archive.writestr(PACKAGE_WORKSHEETS + '/sheet%d.xml' % (i + 1),
                    write_worksheet(sheet, shared_string_table,
                            style_writer.get_style_by_hash()))
            if sheet._charts or sheet._images or sheet.relationships or sheet._comment_count > 0:
                archive.writestr(PACKAGE_WORKSHEETS +
                        '/_rels/sheet%d.xml.rels' % (i + 1),
                        write_worksheet_rels(sheet, drawing_id, comments_id))
            if sheet._charts or sheet._images:
                dw = DrawingWriter(sheet)
                archive.writestr(PACKAGE_DRAWINGS + '/drawing%d.xml' % drawing_id,
                    dw.write())
                archive.writestr(PACKAGE_DRAWINGS + '/_rels/drawing%d.xml.rels' % drawing_id,
                    dw.write_rels(chart_id, image_id)) # TODO remove this dependency
                drawing_id += 1

                for chart in sheet._charts:
                    cw = ChartWriter(chart)
                    archive.writestr(PACKAGE_CHARTS + '/chart%d.xml' % chart_id,
                        cw.write())

                    if chart._shapes:
                        archive.writestr(PACKAGE_CHARTS + '/_rels/chart%d.xml.rels' % chart_id,
                            cw.write_rels(drawing_id)) # TODO remove this dependency
                        sw = ShapeWriter(chart._shapes)
                        archive.writestr(PACKAGE_DRAWINGS + '/drawing%d.xml' % drawing_id,
                            sw.write(shape_id)) # TODO remove this dependency
                        shape_id += len(chart._shapes)
                        drawing_id += 1

                    chart_id += 1

                image_id = self._write_images(sheet._images, archive, image_id)

            if sheet._comment_count > 0:
                cw = CommentWriter(sheet)
                archive.writestr(PACKAGE_XL + '/comments%d.xml' % comments_id,
                    cw.write_comments())
                archive.writestr(PACKAGE_XL + '/drawings/commentsDrawing%d.vml' % comments_id,
                    cw.write_comments_vml())
                comments_id += 1

    def save(self, filename):
        """Write data into the archive."""
        archive = ZipFile(filename, 'w', ZIP_DEFLATED)
        self.write_data(archive)
        archive.close()