1 module libxlsxd.workbook; 2 3 import libxlsxd.xlsxwrap; 4 import std.string : toStringz; 5 import std.typecons : refCounted, RefCounted; 6 7 import libxlsxd.worksheet; 8 import libxlsxd.format; 9 import libxlsxd.chart; 10 import libxlsxd.chartsheet; 11 import libxlsxd.datetime; 12 import libxlsxd.docproperties; 13 14 alias Workbook = RefCounted!WorkbookImpl; 15 16 Workbook newWorkbook(string filename) @trusted { 17 Workbook wb; 18 wb.filename = filename; 19 wb.open(); 20 return wb; 21 } 22 23 struct WorkbookImpl { 24 WorkbookOpen workBook; 25 26 alias workBook this; 27 28 ~this() @safe { 29 this.workBook.close(); 30 } 31 } 32 33 struct WorkbookOpen { 34 import std.exception : enforce; 35 import std.datetime : DateTime; 36 import std.array : empty; 37 lxw_workbook* handle; 38 string filename; 39 40 Format[string] formats; 41 Format dateFormat; 42 Format timeFormat; 43 Format dateTimeFormat; 44 45 static WorkbookOpen opCall(string filename) @safe { 46 WorkbookOpen ret; 47 ret.filename = filename; 48 ret.open(); 49 ret.buildDefaultFormats(); 50 return ret; 51 } 52 53 void open() @trusted { 54 this.handle = workbook_new(this.filename.toStringz()); 55 this.buildDefaultFormats(); 56 } 57 58 void buildDefaultFormats() @safe { 59 this.dateFormat = this.addFormat(); 60 this.dateFormat.setNumFormat("yyyy-mm-dd"); 61 62 this.dateTimeFormat = this.addFormat(); 63 this.dateTimeFormat.setNumFormat("yyyy-mm-ddThh:MM:ss"); 64 65 this.timeFormat = this.addFormat(); 66 this.timeFormat.setNumFormat("hh:MM:ss"); 67 } 68 69 void close() @trusted { 70 if(this.handle !is null) { 71 workbook_close(this.handle); 72 } 73 this.handle = null; 74 } 75 76 WorksheetFluent addFluentWorksheet(string name) @trusted { 77 return WorksheetFluent(&this, this.addWorksheet(name)); 78 } 79 80 Worksheet addWorksheet(string name) nothrow @trusted { 81 return Worksheet(workbook_add_worksheet(this.handle, 82 name.empty ? null : name.toStringz()), 83 &this.dateTimeFormat, &this.dateFormat, &this.timeFormat 84 ); 85 } 86 87 Chartsheet addChartsheet(string name) @trusted { 88 return Chartsheet(workbook_add_chartsheet(this.handle, 89 name.empty ? null : name.toStringz()) 90 ); 91 } 92 93 Format addFormat() nothrow @nogc @trusted { 94 return Format(workbook_add_format(this.handle)); 95 } 96 97 version(No_Overloads_Or_Templates) { 98 Format addFormatNamed(string name) nothrow @safe { 99 return this.addFormatNamedImpl(name); 100 } 101 } else { 102 Format addFormat(string name) nothrow @safe { 103 return this.addFormatNamedImpl(name); 104 } 105 } 106 107 private Format addFormatNamedImpl(string name) nothrow @trusted { 108 auto t = Format(workbook_add_format(this.handle)); 109 this.formats[name] = t; 110 return t; 111 } 112 113 Format getFormat(string name) nothrow @safe { 114 return this.formats[name]; 115 } 116 117 Chart addChart(ubyte chartType) @nogc nothrow @trusted { 118 return Chart(workbook_add_chart(this.handle, chartType)); 119 } 120 121 void setProperties(DocProperties property) @trusted { 122 enforce(workbook_set_properties(this.handle, property.handle) 123 == LXW_NO_ERROR 124 ); 125 } 126 127 version(No_Overloads_Or_Templates) { 128 void setCustomPropertiesBool(string name, bool b) @safe { 129 return this.setCustomPropertiesImpl(name, b); 130 } 131 void setCustomPropertiesInt(string name, long l) @safe { 132 return this.setCustomPropertiesImpl(name, l); 133 } 134 void setCustomPropertiesNumber(string name, double d) @safe { 135 return this.setCustomPropertiesImpl(name, d); 136 } 137 void setCustomPropertiesDateTime(string name, DateTime d) @safe { 138 return this.setCustomPropertiesImpl(name, Datetime.fromDateTime(d)); 139 } 140 } else { 141 alias setCustomProperties = setCustomPropertiesImpl; 142 } 143 144 private void setCustomPropertiesImpl(T)(string name, T t) @trusted { 145 import std.traits : isIntegral, isFloatingPoint, isSomeString; 146 import std.conv : to; 147 148 static if(is(T == bool)) { 149 enforce(workbook_set_custom_property_boolean(this.handle, 150 name.toStringz(), t 151 ) 152 == LXW_NO_ERROR 153 ); 154 } else static if(isIntegral!T) { 155 enforce(workbook_set_custom_property_integer(this.handle, 156 name.toStringz(), to!int(t) 157 ) 158 == LXW_NO_ERROR 159 ); 160 } else static if(isFloatingPoint!T) { 161 enforce(workbook_set_custom_property_number(this.handle, 162 name.toStringz(), to!double(t) 163 ) 164 == LXW_NO_ERROR 165 ); 166 } else static if(is(T == Datetime)) { 167 enforce(workbook_set_custom_property_datetime(this.handle, 168 toStringz(name), &t.handle) 169 == LXW_NO_ERROR 170 ); 171 } else { 172 static assert(false, "setCustomProperties does not work with '" ~ 173 T.stringof ~ "'"); 174 } 175 } 176 177 void defineName(string name, string formula) @trusted { 178 enforce(workbook_define_name(this.handle, name.toStringz(), 179 formula.toStringz() 180 ) 181 == LXW_NO_ERROR 182 ); 183 } 184 185 Worksheet getWorksheetByName(string name) @trusted { 186 return Worksheet(workbook_get_worksheet_by_name(this.handle, 187 name.toStringz() 188 ), 189 &this.dateTimeFormat, &this.dateFormat, &this.timeFormat 190 ); 191 } 192 193 Chartsheet getChartByName(string name) @trusted { 194 return Chartsheet(workbook_get_chartsheet_by_name(this.handle, 195 name.toStringz() 196 ) 197 ); 198 } 199 200 bool validateSheetName(string name) @trusted { 201 return workbook_validate_sheet_name(this.handle, name.toStringz()) 202 == LXW_NO_ERROR; 203 } 204 }