DocX
A small framework that converts NSAttributedString to .docx Word files on iOS and macOS.
Motivation
On iOS, NSAttributedString.DocumentType
supports only HTML and Rich Text, while on macOS .doc and .docx are available options. Even then the .docx exporter on macOS supports only a subset of the attributes of NSAttributedString.
This library is used in SimpleFurigana for macOS and SimpleFurigana for iOS, hence the focus on furigana annotation export.
Installation
Add
.package(name: "DocX", url: "https://github.com/shinjukunian/DocX.git", .branch("master"))
to dependencies
in your Package.swift
file. This requires Swift 5.3, which shipped with Xcode12.
Alternatively, add DocX
in Xcode via File->Swift Packages->Add Package Dependency
, paste https://github.com/shinjukunian/DocX.git
as URL and specify master
as branch.
Usage
let string = NSAttributedString(string: "This is a string", attributes: [.font: UIFont.systemFont(ofSize: UIFont.systemFontSize), .backgroundColor: UIColor.blue])
let url = URL(fileURLWithPath:"myPath")
try? string.writeDocX(to: url)
You can optionally specify MetaData using DocXOptions
:
let font = NSFont(name: "Helvetica", size: 13)! //on macOS
let string = NSAttributedString(string: "The Foundation For Law and Government favours Helvetica.", attributes: [.font: font])
var options = DocXOptions()
options.author = "Michael Knight"
options.title = "Helvetica Document"
let url = URL(fileURLWithPath:"myPath")
try string.writeDocX(to: url, options:options)
See the attached sample projects (for iOS and macOS) for usage and limitations.
On iOS, DocX also includes a UIActivityItemProvider
subclass (DocXActivityItemProvider
) for exporting .docx files through UIActivityViewController
.
NSAttributedString
has no concept of pagination. For manual pagination, use
try DocXWriter.write(pages:[NSAttributedString], to url:URL)
to render each NSAttributedString
as a separate page.
A sample output on macOS opened in Word365.
A sample output on macOS with an embedded image (via NSTextAttachment
). in the macOS sample application (which is a simple NSTextView
), this can be achieved using drag&drop. Note that there is little control over the placement of the image, the image will be inline with text.
A sample output on iOS opened in Word for iOS. Furigana annotations are preserved. The link is clickable. Please note that Quicklook (on both platforms) only supports a limited number of attributes.
Supported Attributes
- most things in
NSAttributedString.Key
(fonts, colors, underline, indents etc.) exceptNSAttributedString.Key.expansion
NSAttributedString.Key.kern
NSAttributedString.Key.ligature
NSAttributedString.Key.obliqueness
NSAttributedString.Key.superscript
(macOS only, doesnt really work for most fonts anyway)NSAttributedString.Key.textEffect
CTRubyAnnotation
for furigana (ruby) annotations in CoreTextNSTextAttachment
embedded images (inline with text)
Some attributes don't have a direct correspondence. For example NSAttributedString
does (typically) not have the concept of a page size.
Dependencies
- my fork of AEXML, many thanks to the original author tadija
- ZipFoundation
Alternatives
- WKDocReader to read old-school .doc files
- BSDocxRipperZipper which supports both reading and writing, but only for a subset of attributes.
References
- OfficeOpenXML Specification
- this blog post on Ruby annotations
- this article on the file structure of the .docx format
Licence
MIT