As soon as you add a USB host port to your microcontroller project, a lot of possibilities suddenly open up. You can add support for plugging in a flash drive for firmware updates, diagnostics, and all kinds of miscellaneous data transfer. One task I’ve needed to complete in the past is the ability to save an Excel .xls spreadsheet. After doing some research, I found that this was actually a fairly difficult task on a microcontroller with limited memory. Most of the C/C++ Excel libraries I’ve found aren’t prepared to work in a microcontroller environment, and they generally do dynamic memory allocation because, well, Excel files are dynamically sized.
I’m going to assume that you already have USB mass storage support figured out for your particular project. This will usually involve using a USB library that provides the USB functionality. Many USB libraries also provide support for accessing mass storage devices. On top of this, you will also need a filesystem library for accessing a FAT32 filesystem, which is arguably the most common filesystem in use on flash drives today. One library I would recommend for working with FAT32 filesystems is FatFS. Note that FatFS doesn’t provide any of the USB functionality — you will have to hook it up to your USB library in diskio.c.
Now, back to the actual file generation. One thing you can do is simply generate a .csv file instead. That strategy works pretty well, and it may end up being all that you need for your particular project. One downside is that in certain cases, it will bring up a dialog box that forces the user to specify options for importing the file. LibreOffice is a particular offender in this regard.
I wanted a solution that generated a real .xls file that Excel and LibreOffice could open without any prompting and didn’t require the use of malloc(). I ended up writing my own library called MicroXLSWriter. MicroXLSWriter is a simple library that should fit on any embedded system. It generates files in a very old .xls format (BIFF2, from Excel 2.0). Modern versions of Excel (tested through Office 2007) can still open BIFF2 files without any problems. My code doesn’t completely follow the BIFF2 format perfectly, but it’s good enough that Excel and LibreOffice don’t seem to complain.
MicroXLSWriter is very limited. It doesn’t support any cell formatting or styles. You can’t customize fonts, colors, borders, or anything like that. The only thing it lets you do is set the width of each column and put text or a number into each cell. For what I needed, this is completely fine. BIFF2 files aren’t typically supported by .xls manipulation libraries, so if you’re generating something that won’t simply be opened by a user with Excel or LibreOffice, you should probably look elsewhere — if you can find a better alternative that still fits in a microcontroller.
If you’re interested, try it out. The source code is on GitHub and it has a very permissive 2-clause BSD license that allows you to use it in whatever commercial or open-source project you want, as long as you follow the simple requirements about preserving the copyright notice in materials distributed with your project (e.g. documentation). If you get a chance, let me know if you use it! I’m curious to hear about various applications where it ends up being used.