Skip to content

Commit

Permalink
Add initial write handler support.
Browse files Browse the repository at this point in the history
Add support for adding user defined types and callbacks to write
additional data types.

Issue #631
  • Loading branch information
jmcnamara committed Jun 9, 2019
1 parent aedafa1 commit 0c8e0ee
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 0 deletions.
37 changes: 37 additions & 0 deletions examples/user_types1.py
@@ -0,0 +1,37 @@
##############################################################################
#
# An example of adding support for user defined types to the XlsxWriter write()
# method.
#
# Copyright 2013-2019, John McNamara, jmcnamara@cpan.org
#
import xlsxwriter
import uuid

# Create a function that will behave like a worksheet write() method.
#
# This function takes a UUID and writes it as as string. It should take the
# parameters shown below and return the return value from the called worksheet
# write_*() method. In this case it changes the UUID to a string and calls
# write_string() to write it.
#
def write_uuid(worksheet, row, col, token, format=None):
return worksheet.write_string(row, col, str(token), format)

# Set up the workbook as usual.
workbook = xlsxwriter.Workbook('user_type1.xlsx')
worksheet = workbook.add_worksheet()

# Make the first column wider for clarity.
worksheet.set_column('A:A', 40)

# Add the write() handler/callback to the worksheet.
worksheet.add_write_handler(uuid.UUID, write_uuid)

# Create a UUID.
my_uuid = uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')

# Write the UUID. This would raise a TypeError without the handler.
worksheet.write('A1', my_uuid)

workbook.close()
40 changes: 40 additions & 0 deletions xlsxwriter/test/comparison/test_types10.py
@@ -0,0 +1,40 @@
###############################################################################
#
# Tests for XlsxWriter.
#
# Copyright (c), 2013-2019, John McNamara, jmcnamara@cpan.org
#

from ..excel_comparsion_test import ExcelComparisonTest
from ...workbook import Workbook
import uuid


def write_uuid(worksheet, row, col, token, format=None):
return worksheet.write_string(row, col, str(token), format)


class TestCompareXLSXFiles(ExcelComparisonTest):
"""
Test file created by XlsxWriter against a file created by Excel.
"""

def setUp(self):

self.set_filename('types10.xlsx')

def test_write_user_type(self):
"""Test writing numbers as text."""

workbook = Workbook(self.got_filename)
worksheet = workbook.add_worksheet()

worksheet.add_write_handler(uuid.UUID, write_uuid)
my_uuid = uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')

worksheet.write('A1', my_uuid)

workbook.close()

self.assertExcelEqual()
Binary file not shown.
31 changes: 31 additions & 0 deletions xlsxwriter/worksheet.py
Expand Up @@ -355,6 +355,8 @@ def __init__(self):
self.vertical_dpi = 0
self.horizontal_dpi = 0

self.write_handlers = {}

# Utility function for writing different types of strings.
def _write_token_as_string(self, token, row, col, *args):
# Map the data to the appropriate write_*() method.
Expand Down Expand Up @@ -426,6 +428,20 @@ def _write(self, row, col, *args):
# Avoid isinstance() for better performance.
token_type = type(token)

# Check for any user defined type handlers with callback functions.
if token_type in self.write_handlers:
write_handler = self.write_handlers[token_type]
function_return = write_handler(self, row, col, *args)

# If the return value is None then the callback has returned
# control to this function and we should continue as
# normal. Otherwise we return the value to the caller and exit.
if function_return is None:
pass
else:
return function_return

# Check for standard Python types.
if token_type is bool:
return self._write_boolean(row, col, *args)

Expand Down Expand Up @@ -1077,6 +1093,21 @@ def _write_rich_string(self, row, col, *args):

return 0

def add_write_handler(self, user_type, user_function):
"""
Add a callback function to the write() method to handle user defined
types.
Args:
user_type: The user type() to match on.
user_function: The user defined function to write the type data..
Returns:
Nothing.
"""

self.write_handlers[user_type] = user_function

@convert_cell_args
def write_row(self, row, col, data, cell_format=None):
"""
Expand Down

0 comments on commit 0c8e0ee

Please sign in to comment.