以编程方式将SQLite数据导出到iOS中的Excel

在我的应用程序中,我使用sqlite作为后端(在本地存储数据)。 我能够插入数据到我的table.but我想要做的是,要导入所有我的sqlite数据到excel以编程方式。我不想使用服务器这个app.once Excel表生成用户应该能够邮寄该表格。 这是可能的iPhone:请帮助我。

以下是我的代码插入数据到表中:

-(IBAction)Login { sqlite3_stmt *stmt; char *errorMsg; char *update1 = "insert into Login1 values (?,?,?,?);"; int x = sqlite3_prepare_v2(database, update1, -1, &stmt, nil); if (x == SQLITE_OK) { sqlite3_bind_text(stmt, 1, NULL,-1, NULL); sqlite3_bind_text(stmt, 2, [USERID UTF8String],-1, NULL); sqlite3_bind_text(stmt, 3, [str1 UTF8String],-1, NULL); sqlite3_bind_text(stmt, 4, [str4 UTF8String],-1, NULL); } if (sqlite3_step(stmt) != SQLITE_DONE) NSLog(@"Error: %@",errorMsg); sqlite3_finalize(stmt); 

}

对于我这样做的应用程序,SQLite数据相当大。 因此,我使用后台线程将所有数据导出为Excel可以导入的CSV(逗号分隔值)文件,然后打开一个带CSV文件的邮件编辑器作为附件。 如果您的数据很小,则可能不需要使用后台线程:

 - (IBAction) export: (id) sender { // in my full code, I start a UIActivityIndicator spinning and show a // message that the app is "Exporting ..." [self performSelectorInBackground: @selector(exportImpl) withObject: nil]; } 

这里是exportImpl

 - (void) exportImpl { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSArray* documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSSystemDomainMask, YES); NSString* documentsDir = [documentPaths objectAtIndex:0]; NSString* csvPath = [documentsDir stringByAppendingPathComponent: @"export.csv"]; // TODO: mutex lock? [sqliteDb exportCsv: csvPath]; [pool release]; // mail is graphical and must be run on UI thread [self performSelectorOnMainThread: @selector(mail:) withObject: csvPath waitUntilDone: NO]; } - (void) mail: (NSString*) filePath { // here I stop animating the UIActivityIndicator // http://howtomakeiphoneapps.com/home/2009/7/14/how-to-make-your-iphone-app-send-email-with-attachments.html BOOL success = NO; if ([MFMailComposeViewController canSendMail]) { // TODO: autorelease pool needed ? NSData* database = [NSData dataWithContentsOfFile: filePath]; if (database != nil) { MFMailComposeViewController* picker = [[MFMailComposeViewController alloc] init]; picker.mailComposeDelegate = self; [picker setSubject:[NSString stringWithFormat: @"%@ %@", [[UIDevice currentDevice] model], [filePath lastPathComponent]]]; NSString* filename = [filePath lastPathComponent]; [picker addAttachmentData: database mimeType:@"application/octet-stream" fileName: filename]; NSString* emailBody = @"Attached is the SQLite data from my iOS device."; [picker setMessageBody:emailBody isHTML:YES]; [self presentModalViewController:picker animated:YES]; success = YES; [picker release]; } } if (!success) { UIAlertView* warning = [[UIAlertView alloc] initWithTitle: @"Error" message: @"Unable to send attachment!" delegate: self cancelButtonTitle: @"Ok" otherButtonTitles: nil]; [warning show]; [warning release]; } } 

然后,我有一个类封装了我所有的SQLite数据。 这个类是唯一一个使sqlite调用。 在这个类中,我有一个将数据导出到我的应用程序caching目录中的CSV文件的方法。 上面代码中的variablessqliteDb是这个类的一个实例。 以下是导出数据的方法:

 -(void) exportCsv: (NSString*) filename { // We record this filename, because the app deletes it on exit self.tempFile = filename; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; // Setup the database object sqlite3* database; // Open the database from the users filessytem if (sqlite3_open([self.databasePath UTF8String], &database) == SQLITE_OK) { [self createTempFile: filename]; NSOutputStream* output = [[NSOutputStream alloc] initToFileAtPath: filename append: YES]; [output open]; if (![output hasSpaceAvailable]) { NSLog(@"No space available in %@", filename); // TODO: UIAlertView? } else { NSString* header = @"Source,Time,Latitude,Longitude,Accuracy\n"; NSInteger result = [output write: [header UTF8String] maxLength: [header length]]; if (result <= 0) { NSLog(@"exportCsv encountered error=%d from header write", result); } BOOL errorLogged = NO; NSString* sqlStatement = @"select timestamp,latitude,longitude,horizontalAccuracy from my_sqlite_table"; // Setup the SQL Statement and compile it for faster access sqlite3_stmt* compiledStatement; if (sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) { // Loop through the results and write them to the CSV file while (sqlite3_step(compiledStatement) == SQLITE_ROW) { // Read the data from the result row NSInteger secondsSinceReferenceDate = (NSInteger)sqlite3_column_double(compiledStatement, 0); float lat = (float)sqlite3_column_double(compiledStatement, 1); float lon = (float)sqlite3_column_double(compiledStatement, 2); float accuracy = (float)sqlite3_column_double(compiledStatement, 3); if (lat != 0 && lon != 0) { NSDate* timestamp = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate: secondsSinceReferenceDate]; NSString* line = [[NSString alloc] initWithFormat: @"%@,%@,%f,%f,%d\n", table, [dateFormatter stringFromDate: timestamp], lat, lon, (NSInteger)accuracy]; result = [output write: [line UTF8String] maxLength: [line length]]; if (!errorLogged && (result <= 0)) { NSLog(@"exportCsv write returned %d", result); errorLogged = YES; } [line release]; [timestamp release]; } // Release the compiled statement from memory sqlite3_finalize(compiledStatement); } } } [output close]; [output release]; } sqlite3_close(database); [pool release]; } -(void) createTempFile: (NSString*) filename { NSFileManager* fileSystem = [NSFileManager defaultManager]; [fileSystem removeItemAtPath: filename error: nil]; NSMutableDictionary* attributes = [[NSMutableDictionary alloc] init]; NSNumber* permission = [NSNumber numberWithLong: 0640]; [attributes setObject: permission forKey: NSFilePosixPermissions]; if (![fileSystem createFileAtPath: filename contents: nil attributes: attributes]) { NSLog(@"Unable to create temp file for exporting CSV."); // TODO: UIAlertView? } [attributes release]; } 

我的代码是导出位置信息的数据库。 很明显,在exportCsv里面,你需要把我的sqlite调用replace为适合你的数据库内容的调用。

此外,代码将数据存储在临时文件中。 您可能要决定何时清理这些临时文件。

很明显,这个代码是在ARC可用之前编写的。 根据需要调整。