diff --git a/dev/docs/source/worksheet.rst b/dev/docs/source/worksheet.rst index 6935ee871..26e4f434d 100644 --- a/dev/docs/source/worksheet.rst +++ b/dev/docs/source/worksheet.rst @@ -966,12 +966,13 @@ position and scale the image. The available parameters with their default values are:: { - 'x_offset': 0, - 'y_offset': 0, - 'x_scale': 1, - 'y_scale': 1, - 'url': None, - 'tip': None, + 'x_offset': 0, + 'y_offset': 0, + 'x_scale': 1, + 'y_scale': 1, + 'url': None, + 'tip': None, + 'positioning': None } The offset values are in pixels:: @@ -994,6 +995,18 @@ parameter gives an option mouseover tooltip for images with hyperlinks:: See also :func:`write_url` for details on supported URIs. +The ``positioning`` parameter can be used to control the object positioning +of the image:: + + worksheet.insert_image('B3', 'python.png', {'positioning': 1}) + +Where ``positioning`` has the following allowable values: + +1. Move and size with cells. +2. Move but don't size with cells (the default). +3. Don't move or size with cells. + + .. Note:: The scaling of a image may be affected if is crosses a row that has its default height changed due to a font that is larger than the default font diff --git a/xlsxwriter/drawing.py b/xlsxwriter/drawing.py index fcd829e1f..daf306c54 100644 --- a/xlsxwriter/drawing.py +++ b/xlsxwriter/drawing.py @@ -86,12 +86,14 @@ def _add_drawing_object(self, drawing_object): 'description': drawing_object[13], 'shape': drawing_object[14], 'url': None, - 'tip': None + 'tip': None, + 'anchor': None } if len(drawing_object) > 15: obj['url'] = drawing_object[15] obj['tip'] = drawing_object[16] + obj['anchor'] = drawing_object[17] self.drawings.append(obj) @@ -128,7 +130,12 @@ def _write_two_cell_anchor(self, index, drawing): # Add attribute for images. if drawing['anchor_type'] == 2: - attributes.append(('editAs', 'oneCell')) + if drawing['anchor'] == 3: + attributes.append(('editAs', 'absolute')) + elif drawing['anchor'] == 1: + pass + else: + attributes.append(('editAs', 'oneCell')) # Add editAs attribute for shapes. if shape and shape.editAs: diff --git a/xlsxwriter/test/comparison/test_image_anchor01.py b/xlsxwriter/test/comparison/test_image_anchor01.py new file mode 100644 index 000000000..20b02a2e4 --- /dev/null +++ b/xlsxwriter/test/comparison/test_image_anchor01.py @@ -0,0 +1,88 @@ +############################################################################### +# +# Tests for XlsxWriter. +# +# Copyright (c), 2013-2014, John McNamara, jmcnamara@cpan.org +# + +import unittest +import os +from ...workbook import Workbook +from ..helperfunctions import _compare_xlsx_files + + +class TestCompareXLSXFiles(unittest.TestCase): + """ + Test file created by XlsxWriter against a file created by Excel. + + """ + + def setUp(self): + self.maxDiff = None + + filename = 'image_anchor01.xlsx' + + test_dir = 'xlsxwriter/test/comparison/' + self.image_dir = test_dir + 'images/' + self.got_filename = test_dir + '_test_' + filename + self.exp_filename = test_dir + 'xlsx_files/' + filename + + self.ignore_files = [] + self.ignore_elements = {} + + def test_create_file(self): + """Test the creation of a simple XlsxWriter file with image(s).""" + filename = self.got_filename + + #################################################### + + workbook = Workbook(filename) + + worksheet = workbook.add_worksheet() + + worksheet.insert_image( + 'E9', self.image_dir + 'red.png', {'positioning': 3}) + + workbook.close() + + #################################################### + + got, exp = _compare_xlsx_files(self.got_filename, + self.exp_filename, + self.ignore_files, + self.ignore_elements) + + self.assertEqual(got, exp) + + def test_create_file_in_memory(self): + """Test the creation of a simple XlsxWriter file with image(s).""" + filename = self.got_filename + + #################################################### + + workbook = Workbook(filename, {'in_memory': True}) + + worksheet = workbook.add_worksheet() + + worksheet.insert_image( + 'E9', self.image_dir + 'red.png', {'positioning': 3}) + + workbook.close() + + #################################################### + + got, exp = _compare_xlsx_files(self.got_filename, + self.exp_filename, + self.ignore_files, + self.ignore_elements) + + self.assertEqual(got, exp) + + def tearDown(self): + # Cleanup. + if os.path.exists(self.got_filename): + os.remove(self.got_filename) + + +if __name__ == '__main__': + unittest.main() diff --git a/xlsxwriter/test/comparison/test_image_anchor02.py b/xlsxwriter/test/comparison/test_image_anchor02.py new file mode 100644 index 000000000..d4016b3b5 --- /dev/null +++ b/xlsxwriter/test/comparison/test_image_anchor02.py @@ -0,0 +1,88 @@ +############################################################################### +# +# Tests for XlsxWriter. +# +# Copyright (c), 2013-2014, John McNamara, jmcnamara@cpan.org +# + +import unittest +import os +from ...workbook import Workbook +from ..helperfunctions import _compare_xlsx_files + + +class TestCompareXLSXFiles(unittest.TestCase): + """ + Test file created by XlsxWriter against a file created by Excel. + + """ + + def setUp(self): + self.maxDiff = None + + filename = 'image_anchor02.xlsx' + + test_dir = 'xlsxwriter/test/comparison/' + self.image_dir = test_dir + 'images/' + self.got_filename = test_dir + '_test_' + filename + self.exp_filename = test_dir + 'xlsx_files/' + filename + + self.ignore_files = [] + self.ignore_elements = {} + + def test_create_file(self): + """Test the creation of a simple XlsxWriter file with image(s).""" + filename = self.got_filename + + #################################################### + + workbook = Workbook(filename) + + worksheet = workbook.add_worksheet() + + worksheet.insert_image( + 'E9', self.image_dir + 'red.png', {'positioning': 2}) + + workbook.close() + + #################################################### + + got, exp = _compare_xlsx_files(self.got_filename, + self.exp_filename, + self.ignore_files, + self.ignore_elements) + + self.assertEqual(got, exp) + + def test_create_file_in_memory(self): + """Test the creation of a simple XlsxWriter file with image(s).""" + filename = self.got_filename + + #################################################### + + workbook = Workbook(filename, {'in_memory': True}) + + worksheet = workbook.add_worksheet() + + worksheet.insert_image( + 'E9', self.image_dir + 'red.png', {'positioning': 2}) + + workbook.close() + + #################################################### + + got, exp = _compare_xlsx_files(self.got_filename, + self.exp_filename, + self.ignore_files, + self.ignore_elements) + + self.assertEqual(got, exp) + + def tearDown(self): + # Cleanup. + if os.path.exists(self.got_filename): + os.remove(self.got_filename) + + +if __name__ == '__main__': + unittest.main() diff --git a/xlsxwriter/test/comparison/test_image_anchor03.py b/xlsxwriter/test/comparison/test_image_anchor03.py new file mode 100644 index 000000000..79eb512dc --- /dev/null +++ b/xlsxwriter/test/comparison/test_image_anchor03.py @@ -0,0 +1,88 @@ +############################################################################### +# +# Tests for XlsxWriter. +# +# Copyright (c), 2013-2014, John McNamara, jmcnamara@cpan.org +# + +import unittest +import os +from ...workbook import Workbook +from ..helperfunctions import _compare_xlsx_files + + +class TestCompareXLSXFiles(unittest.TestCase): + """ + Test file created by XlsxWriter against a file created by Excel. + + """ + + def setUp(self): + self.maxDiff = None + + filename = 'image_anchor03.xlsx' + + test_dir = 'xlsxwriter/test/comparison/' + self.image_dir = test_dir + 'images/' + self.got_filename = test_dir + '_test_' + filename + self.exp_filename = test_dir + 'xlsx_files/' + filename + + self.ignore_files = [] + self.ignore_elements = {} + + def test_create_file(self): + """Test the creation of a simple XlsxWriter file with image(s).""" + filename = self.got_filename + + #################################################### + + workbook = Workbook(filename) + + worksheet = workbook.add_worksheet() + + worksheet.insert_image( + 'E9', self.image_dir + 'red.png', {'positioning': 1}) + + workbook.close() + + #################################################### + + got, exp = _compare_xlsx_files(self.got_filename, + self.exp_filename, + self.ignore_files, + self.ignore_elements) + + self.assertEqual(got, exp) + + def test_create_file_in_memory(self): + """Test the creation of a simple XlsxWriter file with image(s).""" + filename = self.got_filename + + #################################################### + + workbook = Workbook(filename, {'in_memory': True}) + + worksheet = workbook.add_worksheet() + + worksheet.insert_image( + 'E9', self.image_dir + 'red.png', {'positioning': 1}) + + workbook.close() + + #################################################### + + got, exp = _compare_xlsx_files(self.got_filename, + self.exp_filename, + self.ignore_files, + self.ignore_elements) + + self.assertEqual(got, exp) + + def tearDown(self): + # Cleanup. + if os.path.exists(self.got_filename): + os.remove(self.got_filename) + + +if __name__ == '__main__': + unittest.main() diff --git a/xlsxwriter/test/comparison/test_image_anchor04.py b/xlsxwriter/test/comparison/test_image_anchor04.py new file mode 100644 index 000000000..ee232a265 --- /dev/null +++ b/xlsxwriter/test/comparison/test_image_anchor04.py @@ -0,0 +1,65 @@ +############################################################################### +# +# Tests for XlsxWriter. +# +# Copyright (c), 2013-2014, John McNamara, jmcnamara@cpan.org +# + +import unittest +import os +from ...workbook import Workbook +from ..helperfunctions import _compare_xlsx_files + + +class TestCompareXLSXFiles(unittest.TestCase): + """ + Test file created by XlsxWriter against a file created by Excel. + + """ + + def setUp(self): + self.maxDiff = None + + filename = 'image_anchor04.xlsx' + + test_dir = 'xlsxwriter/test/comparison/' + self.image_dir = test_dir + 'images/' + self.got_filename = test_dir + '_test_' + filename + self.exp_filename = test_dir + 'xlsx_files/' + filename + + self.ignore_files = [] + self.ignore_elements = {} + + def test_create_file(self): + """Test the creation of a simple XlsxWriter file with image(s).""" + filename = self.got_filename + + #################################################### + + workbook = Workbook(filename) + + worksheet = workbook.add_worksheet() + + worksheet.insert_image( + 'D7', self.image_dir + 'yellow.png', + {'x_offset': 1, 'y_offset': 2, 'positioning': 3}) + + workbook.close() + + #################################################### + + got, exp = _compare_xlsx_files(self.got_filename, + self.exp_filename, + self.ignore_files, + self.ignore_elements) + + self.assertEqual(got, exp) + + def tearDown(self): + # Cleanup. + if os.path.exists(self.got_filename): + os.remove(self.got_filename) + + +if __name__ == '__main__': + unittest.main() diff --git a/xlsxwriter/test/comparison/test_image_anchor05.py b/xlsxwriter/test/comparison/test_image_anchor05.py new file mode 100644 index 000000000..e2f2813c3 --- /dev/null +++ b/xlsxwriter/test/comparison/test_image_anchor05.py @@ -0,0 +1,65 @@ +############################################################################### +# +# Tests for XlsxWriter. +# +# Copyright (c), 2013-2014, John McNamara, jmcnamara@cpan.org +# + +import unittest +import os +from ...workbook import Workbook +from ..helperfunctions import _compare_xlsx_files + + +class TestCompareXLSXFiles(unittest.TestCase): + """ + Test file created by XlsxWriter against a file created by Excel. + + """ + + def setUp(self): + self.maxDiff = None + + filename = 'image_anchor05.xlsx' + + test_dir = 'xlsxwriter/test/comparison/' + self.image_dir = test_dir + 'images/' + self.got_filename = test_dir + '_test_' + filename + self.exp_filename = test_dir + 'xlsx_files/' + filename + + self.ignore_files = [] + self.ignore_elements = {} + + def test_create_file(self): + """Test the creation of a simple XlsxWriter file with image(s).""" + filename = self.got_filename + + #################################################### + + workbook = Workbook(filename) + + worksheet = workbook.add_worksheet() + + worksheet.insert_image( + 'D7', self.image_dir + 'yellow.png', + {'x_offset': 1, 'y_offset': 2, 'positioning': 2}) + + workbook.close() + + #################################################### + + got, exp = _compare_xlsx_files(self.got_filename, + self.exp_filename, + self.ignore_files, + self.ignore_elements) + + self.assertEqual(got, exp) + + def tearDown(self): + # Cleanup. + if os.path.exists(self.got_filename): + os.remove(self.got_filename) + + +if __name__ == '__main__': + unittest.main() diff --git a/xlsxwriter/test/comparison/test_image_anchor06.py b/xlsxwriter/test/comparison/test_image_anchor06.py new file mode 100644 index 000000000..afbb80f44 --- /dev/null +++ b/xlsxwriter/test/comparison/test_image_anchor06.py @@ -0,0 +1,65 @@ +############################################################################### +# +# Tests for XlsxWriter. +# +# Copyright (c), 2013-2014, John McNamara, jmcnamara@cpan.org +# + +import unittest +import os +from ...workbook import Workbook +from ..helperfunctions import _compare_xlsx_files + + +class TestCompareXLSXFiles(unittest.TestCase): + """ + Test file created by XlsxWriter against a file created by Excel. + + """ + + def setUp(self): + self.maxDiff = None + + filename = 'image_anchor06.xlsx' + + test_dir = 'xlsxwriter/test/comparison/' + self.image_dir = test_dir + 'images/' + self.got_filename = test_dir + '_test_' + filename + self.exp_filename = test_dir + 'xlsx_files/' + filename + + self.ignore_files = [] + self.ignore_elements = {} + + def test_create_file(self): + """Test the creation of a simple XlsxWriter file with image(s).""" + filename = self.got_filename + + #################################################### + + workbook = Workbook(filename) + + worksheet = workbook.add_worksheet() + + worksheet.insert_image( + 'D7', self.image_dir + 'yellow.png', + {'x_offset': 1, 'y_offset': 2, 'positioning': 1}) + + workbook.close() + + #################################################### + + got, exp = _compare_xlsx_files(self.got_filename, + self.exp_filename, + self.ignore_files, + self.ignore_elements) + + self.assertEqual(got, exp) + + def tearDown(self): + # Cleanup. + if os.path.exists(self.got_filename): + os.remove(self.got_filename) + + +if __name__ == '__main__': + unittest.main() diff --git a/xlsxwriter/test/comparison/test_image_anchor07.py b/xlsxwriter/test/comparison/test_image_anchor07.py new file mode 100644 index 000000000..f3a621ccc --- /dev/null +++ b/xlsxwriter/test/comparison/test_image_anchor07.py @@ -0,0 +1,69 @@ +############################################################################### +# +# Tests for XlsxWriter. +# +# Copyright (c), 2013-2014, John McNamara, jmcnamara@cpan.org +# + +import unittest +import os +from ...workbook import Workbook +from ..helperfunctions import _compare_xlsx_files + + +class TestCompareXLSXFiles(unittest.TestCase): + """ + Test file created by XlsxWriter against a file created by Excel. + + """ + + def setUp(self): + self.maxDiff = None + + filename = 'image_anchor07.xlsx' + + test_dir = 'xlsxwriter/test/comparison/' + self.image_dir = test_dir + 'images/' + self.got_filename = test_dir + '_test_' + filename + self.exp_filename = test_dir + 'xlsx_files/' + filename + + self.ignore_files = [] + self.ignore_elements = {} + + def test_create_file(self): + """Test the creation of a simple XlsxWriter file with image(s).""" + filename = self.got_filename + + #################################################### + + workbook = Workbook(filename) + + worksheet = workbook.add_worksheet() + + worksheet.insert_image('A1', self.image_dir + 'blue.png') + worksheet.insert_image( + 'B3', self.image_dir + 'red.jpg', {'positioning': 3}) + worksheet.insert_image( + 'D5', self.image_dir + 'yellow.jpg', {'positioning': 2}) + worksheet.insert_image( + 'F9', self.image_dir + 'grey.png', {'positioning': 1}) + + workbook.close() + + #################################################### + + got, exp = _compare_xlsx_files(self.got_filename, + self.exp_filename, + self.ignore_files, + self.ignore_elements) + + self.assertEqual(got, exp) + + def tearDown(self): + # Cleanup. + if os.path.exists(self.got_filename): + os.remove(self.got_filename) + + +if __name__ == '__main__': + unittest.main() diff --git a/xlsxwriter/test/comparison/xlsx_files/image_anchor01.xlsx b/xlsxwriter/test/comparison/xlsx_files/image_anchor01.xlsx new file mode 100644 index 000000000..079d2d3a4 Binary files /dev/null and b/xlsxwriter/test/comparison/xlsx_files/image_anchor01.xlsx differ diff --git a/xlsxwriter/test/comparison/xlsx_files/image_anchor02.xlsx b/xlsxwriter/test/comparison/xlsx_files/image_anchor02.xlsx new file mode 100644 index 000000000..51f8538b0 Binary files /dev/null and b/xlsxwriter/test/comparison/xlsx_files/image_anchor02.xlsx differ diff --git a/xlsxwriter/test/comparison/xlsx_files/image_anchor03.xlsx b/xlsxwriter/test/comparison/xlsx_files/image_anchor03.xlsx new file mode 100644 index 000000000..8404893c5 Binary files /dev/null and b/xlsxwriter/test/comparison/xlsx_files/image_anchor03.xlsx differ diff --git a/xlsxwriter/test/comparison/xlsx_files/image_anchor04.xlsx b/xlsxwriter/test/comparison/xlsx_files/image_anchor04.xlsx new file mode 100644 index 000000000..a2e024f99 Binary files /dev/null and b/xlsxwriter/test/comparison/xlsx_files/image_anchor04.xlsx differ diff --git a/xlsxwriter/test/comparison/xlsx_files/image_anchor05.xlsx b/xlsxwriter/test/comparison/xlsx_files/image_anchor05.xlsx new file mode 100644 index 000000000..b0b4d41aa Binary files /dev/null and b/xlsxwriter/test/comparison/xlsx_files/image_anchor05.xlsx differ diff --git a/xlsxwriter/test/comparison/xlsx_files/image_anchor06.xlsx b/xlsxwriter/test/comparison/xlsx_files/image_anchor06.xlsx new file mode 100644 index 000000000..182034573 Binary files /dev/null and b/xlsxwriter/test/comparison/xlsx_files/image_anchor06.xlsx differ diff --git a/xlsxwriter/test/comparison/xlsx_files/image_anchor07.xlsx b/xlsxwriter/test/comparison/xlsx_files/image_anchor07.xlsx new file mode 100644 index 000000000..0984656cb Binary files /dev/null and b/xlsxwriter/test/comparison/xlsx_files/image_anchor07.xlsx differ diff --git a/xlsxwriter/test/drawing/test_drawing_image01.py b/xlsxwriter/test/drawing/test_drawing_image01.py index 410e06123..808a079b9 100644 --- a/xlsxwriter/test/drawing/test_drawing_image01.py +++ b/xlsxwriter/test/drawing/test_drawing_image01.py @@ -90,7 +90,7 @@ def test_assemble_xml_file_with_url(self): tip = 'this is a tooltip' url = 'https://www.github.com' - drawing._add_drawing_object([2, 2, 1, 0, 0, 3, 6, 533257, 190357, 1219200, 190500, 1142857, 1142857, 'republic.png', None, url, tip]) + drawing._add_drawing_object([2, 2, 1, 0, 0, 3, 6, 533257, 190357, 1219200, 190500, 1142857, 1142857, 'republic.png', None, url, tip, None]) drawing.embedded = 1 drawing._assemble_xml_file() diff --git a/xlsxwriter/worksheet.py b/xlsxwriter/worksheet.py index bdb931edc..62f07a8a7 100644 --- a/xlsxwriter/worksheet.py +++ b/xlsxwriter/worksheet.py @@ -1035,9 +1035,10 @@ def insert_image(self, row, col, image, options={}): y_scale = options.get('y_scale', 1) url = options.get('url', None) tip = options.get('tip', None) + anchor = options.get('positioning', None) self.images.append([row, col, image, x_offset, y_offset, - x_scale, y_scale, url, tip]) + x_scale, y_scale, url, tip, anchor]) @convert_cell_args def insert_chart(self, row, col, chart, options={}): @@ -3567,8 +3568,8 @@ def _prepare_image(self, index, image_id, drawing_id, width, height, name, image_type): # Set up images/drawings. drawing_type = 2 - (row, col, _, x_offset, y_offset, x_scale, y_scale, url, tip) = \ - self.images[index] + (row, col, _, x_offset, y_offset, + x_scale, y_scale, url, tip, anchor) = self.images[index] width *= x_scale height *= y_scale @@ -3595,7 +3596,7 @@ def _prepare_image(self, index, image_id, drawing_id, width, height, drawing_object = [drawing_type] drawing_object.extend(dimensions) - drawing_object.extend([width, height, name, None, url, tip]) + drawing_object.extend([width, height, name, None, url, tip, anchor]) drawing._add_drawing_object(drawing_object)