iOS創(chuàng)建execl表格、excel數(shù)據(jù)插入、導(dǎo)出excel

我使用的是C語(yǔ)言編寫(xiě)的庫(kù)libxlsxwriter創(chuàng)建的excel表格,用法在libxlsxwriter英文文檔
,導(dǎo)出/預(yù)覽/分享excel,使用的是原生的UIDocumentInteractionController實(shí)現(xiàn)的。

在項(xiàng)目中的使用步驟如下

步驟一:使用cocoapods下載libxlsxwriter至項(xiàng)目,我的項(xiàng)目文件名為feiyangApp

1-1: 打開(kāi)Terminal終端,輸入cd /Users/zhangbin/Desktop/feiyang/feiyangApp進(jìn)入項(xiàng)目feiyangApp
1-2:終端輸入 vim Podfile,進(jìn)入該文件
1-3:進(jìn)入Podfile文件后,輸入i,進(jìn)入編輯模式。(出現(xiàn)-- INSERT --就說(shuō)明進(jìn)入編輯模式)
1-4 : 在該文件中輸入pod 'libxlsxwriter'
1-5 : 先按esc,再輸入 :wq,保存剛才的編輯操作再退出。
1-6 : 終端中輸入pod install --verbose --no-repo-update,安裝libxlsxwriter庫(kù),且不更新已安裝的其他庫(kù)。

image.png

image.png

在項(xiàng)目中查看是否安裝成功
image.png

步驟二:oc項(xiàng)目中使用libxlsxwriter

2.1導(dǎo)入#import <xlsxwriter/xlsxwriter.h>

2.2 表格數(shù)據(jù)源如下

{
  "status" : 200,
  "msg" : "OK",
  "data" : [
    {
      "accountNo" : "16160308190000014623",
      "paymentTime" : 1590818573000,
      "allInPayOrderNo" : "1266608536524165120",
      "discountMoney" : 0,
      "title" : "炸雞原料",
      "orderNo" : "1590817979569664160",
      "price" : 1,
      "num" : "1",
      "benefitCategoryName" : "其他",
      "companyName" : "山東xxxxxx科技有限公司",
      "benefitCategoryCode" : "W101103105101",
      "orderInfo" : "{"商品名稱(chēng)":"炸雞原料","商品分類(lèi)代碼":"W101103105101","商品數(shù)量":"1","商品單價(jià)":1.00,"商品分類(lèi)名稱(chēng)":"其他"}",
      "originalPayment" : 1,
      "payment" : 1,
      "couponName" : null
    },
    {
      "accountNo" : "16160308190000014623",
      "paymentTime" : 1591344525000,
      "allInPayOrderNo" : "1268816331247988736",
      "discountMoney" : 10,
      "title" : "炸雞原料",
      "orderNo" : "1591343029512428230",
      "price" : 1,
      "num" : "109",
      "benefitCategoryName" : "其他",
      "companyName" : "山東xxxxxx科技有限公司",
      "benefitCategoryCode" : "W101103105101",
      "orderInfo" : "{"商品名稱(chēng)":"炸雞原料","商品分類(lèi)代碼":"W101103105101","商品數(shù)量":"109","商品單價(jià)":1.00,"商品分類(lèi)名稱(chēng)":"其他"}",
      "originalPayment" : 10.02,
      "payment" : 0.02,
      "couponName" : null
    },
    {
      "accountNo" : "16160308190000014623",
      "paymentTime" : 1591348105000,
      "allInPayOrderNo" : "1268831237196234752",
      "discountMoney" : 20,
      "title" : "炸雞原料",
      "orderNo" : "1591347802389069549",
      "price" : 1,
      "num" : "104",
      "benefitCategoryName" : "其他",
      "companyName" : "山東xxxxxx科技有限公司",
      "benefitCategoryCode" : "W101103105101",
      "orderInfo" : "{"商品名稱(chēng)":"炸雞原料","商品分類(lèi)代碼":"W101103105101","商品數(shù)量":"104","商品單價(jià)":1.00,"商品分類(lèi)名稱(chēng)":"其他"}",
      "originalPayment" : 20.02,
      "payment" : 0.02,
      "couponName" : null
    }
  ]
}

2.3 主要代碼如下

#import "ZB_AccountStatementController.h"
#import "ZB_AccountModel.h"
#import <xlsxwriter/xlsxwriter.h>

@interface ZB_AccountStatementController ()<UIDocumentInteractionControllerDelegate>
@property (nonatomic,strong) NSMutableArray<ZB_AccountModel *> *accountDataArray;
@property (nonatomic,strong) UIButton * exportAccountBtn;
@property (nonatomic,strong)UIDocumentInteractionController * document;
@property(nonatomic,assign) NSInteger startYear;
@property(nonatomic,assign) NSInteger startMonth;
@property(nonatomic,assign) NSInteger startDay;
@property(nonatomic,assign) NSInteger endYear;
@property(nonatomic,assign) NSInteger endMonth;
@property(nonatomic,assign) NSInteger endDay;
@end

@implementation ZB_AccountStatementController

-(NSMutableArray *)accountDataArray{
    if(!_accountDataArray){
        _accountDataArray = [NSMutableArray array];
    }
    return _accountDataArray;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self exportAccountUI];
    [self netRequest];
}

-(void)exportAccountUI{
    int navH = (int)NAV_HEIGHT;
    self.exportAccountBtn = [[UIButton alloc]initWithFrame:CGRectMake(0,APP_SCREEN_HEIGHT - navH - BOTTOM_SAFE_AREA - tRealLength(35) ,APP_SCREEN_WIDTH,tRealLength(35))];
    self.exportAccountBtn.backgroundColor = [UIColor whiteColor];
    [self.exportAccountBtn setTitle:@"導(dǎo)出當(dāng)前對(duì)賬單" forState:UIControlStateNormal];
    [self.exportAccountBtn setImage:[UIImage imageNamed:@"benefit_export.png"] forState:UIControlStateNormal];
    [self.exportAccountBtn setTitleColor:[UIColor colorWithHexString:@"#a61b29"] forState:UIControlStateNormal];
    self.exportAccountBtn.titleLabel.font  = [UIFont systemFontOfSize:tRealFontSize(14)];
    [self.exportAccountBtn addTarget:self action:@selector(exportAccountClick:) forControlEvents:UIControlEventTouchUpInside];
    self.exportAccountBtn.hidden = YES;
    [self.view addSubview:self.exportAccountBtn];
}
-(void)netRequest{
    
    // ....
    // 數(shù)據(jù)請(qǐng)求,拿到數(shù)據(jù)源
    
    // 指定路徑下創(chuàng)建excel
    [self creationExcel];
}

// 創(chuàng)建excel
-(void)creationExcel{
    // 獲取cache路徑
    NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *xlsxName = [NSString stringWithFormat:@"%ld年%ld月%ld日-%ld年%ld月%ld日對(duì)賬單.xlsx",self.startYear,self.startMonth,self.startDay,self.endYear,self.endMonth,self.endDay];
    // 拼接 cache路徑 + 名為xlsxName的文件   注意:該路徑下的文件名一定要和后續(xù)導(dǎo)出的文件名保持一致,否則后續(xù)執(zhí)行導(dǎo)出操作時(shí),讀取不到該文件
    NSString *filename = [documentDirectory stringByAppendingPathComponent:xlsxName];
    
    // 創(chuàng)建新xlsx文件,路徑需要轉(zhuǎn)成c字符串
    lxw_workbook  *workbook  = workbook_new([filename UTF8String]);
    // 創(chuàng)建sheet
    lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
    
    // 格式1
    lxw_format *titleformat = workbook_add_format(workbook);
    // 加粗
    format_set_bold(titleformat);
    // 字體尺寸
    format_set_font_size(titleformat, 20);
    // 內(nèi)容垂直居中
    format_set_align(titleformat, LXW_ALIGN_VERTICAL_CENTER);
    // 內(nèi)容水平居中
    format_set_align(titleformat, LXW_ALIGN_CENTER);
    // 合并單元格。0行0列到0行8列合并為一行,并設(shè)定內(nèi)容為"(山東)文旅惠民消費(fèi)券《核銷(xiāo)結(jié)算表》"
    worksheet_merge_range(worksheet, 0, 0,0, 8, [@"(山東)文旅惠民消費(fèi)券《核銷(xiāo)結(jié)算表》" cStringUsingEncoding:NSUTF8StringEncoding], titleformat);
    
    // 格式2
    lxw_format *columnTitleformat = workbook_add_format(workbook);
    // 內(nèi)容垂直居中
    format_set_align(columnTitleformat, LXW_ALIGN_VERTICAL_CENTER);
    // 內(nèi)容水平居中
    format_set_align(columnTitleformat, LXW_ALIGN_CENTER);
    
    
    // 將"統(tǒng)計(jì)周期:" 的總價(jià)寫(xiě)入到1行5列
    worksheet_write_string(worksheet, 1, 5, [@"統(tǒng)計(jì)周期:" UTF8String], columnTitleformat);
    // 將"填報(bào)日期:" 的總價(jià)寫(xiě)入到1行7列
    worksheet_write_string(worksheet, 1, 7, [@"填報(bào)日期:" UTF8String], columnTitleformat);
    // 第1行的高度為20,并將格式2應(yīng)用到該行上。注意 行的高度和列表的寬度的值單位不一樣,此50非彼50
    worksheet_set_row(worksheet, 1, 30, columnTitleformat);
    
    
    // 第0列到第8列的寬度為30。注意 此30非彼30
    worksheet_set_column(worksheet, 0, 8, 30.0, NULL);
    // 第2行的高度為30,并將格式2應(yīng)用到該行上。注意 行的高度和列表的寬度的值單位不一樣,此30非彼30
    worksheet_set_row(worksheet, 2, 30, columnTitleformat);
    
    // 將"序號(hào)"寫(xiě)入到2行0列
    worksheet_write_string(worksheet, 2, 0, [@"序號(hào)" UTF8String], columnTitleformat);
    // 將"企業(yè)名稱(chēng)"寫(xiě)入到2行1列
    worksheet_write_string(worksheet, 2, 1, [@"企業(yè)名稱(chēng)" UTF8String], columnTitleformat);
    // 將"商家賬號(hào)"寫(xiě)入到2行2列
    worksheet_write_string(worksheet, 2, 2, [@"商家賬號(hào)" UTF8String], columnTitleformat);
    // 將"消費(fèi)日期"寫(xiě)入到2行3列
    worksheet_write_string(worksheet, 2, 3, [@"消費(fèi)日期" UTF8String], columnTitleformat);
    // 將"銷(xiāo)售訂單號(hào)"寫(xiě)入到2行4列
    worksheet_write_string(worksheet, 2, 4, [@"銷(xiāo)售訂單號(hào)" UTF8String], columnTitleformat);
    // 將"銷(xiāo)售金額"寫(xiě)入到2行5列
    worksheet_write_string(worksheet, 2, 5, [@"銷(xiāo)售金額" UTF8String], columnTitleformat);
    // 將"通聯(lián)訂單號(hào)"寫(xiě)入到2行6列
    worksheet_write_string(worksheet, 2, 6, [@"通聯(lián)訂單號(hào)" UTF8String], columnTitleformat);
    // 將"優(yōu)惠(券)"寫(xiě)入到2行7列
    worksheet_write_string(worksheet, 2, 7, [@"優(yōu)惠(券)" UTF8String], columnTitleformat);
    // 將"實(shí)付金額"寫(xiě)入到2行8列
    worksheet_write_string(worksheet, 2, 8, [@"實(shí)付金額" UTF8String], columnTitleformat);
    
    
    int  rowA = 3 + (int)self.accountDataArray.count;
    // 合并單元格。rowA行0列 到 rowA行5列合并為一行,并設(shè)定內(nèi)容為 "合計(jì):"
    worksheet_merge_range(worksheet, rowA,  0 ,rowA, 5, [@"合計(jì):" cStringUsingEncoding:NSUTF8StringEncoding], columnTitleformat);
    // 第rowA行的高度為50。注意 行的高度和列表的寬度的值單位不一樣,此50非彼50
    worksheet_set_row(worksheet, rowA, 50, columnTitleformat);
    
    
    float discountPrice = 0.00;
    float realPrice = 0.00;
    // 統(tǒng)計(jì) 優(yōu)惠(券)所在列的總價(jià) 和 實(shí)付金額 所在列的總價(jià)
    for (int i = 0; i < self.accountDataArray.count; i++) {
        ZB_AccountModel *model = self.accountDataArray[i];
        discountPrice = discountPrice + [model.discountMoney floatValue];
        realPrice = realPrice + [model.payment floatValue];
    }
    // 將優(yōu)惠(券)所在列的總價(jià)寫(xiě)入到rowA行7列
    worksheet_write_string(worksheet, rowA, 7, [[NSString stringWithFormat:@"%.2lf",discountPrice] UTF8String], columnTitleformat);
    // 將實(shí)付金額 所在列的總價(jià)寫(xiě)入到rowA行8列
    worksheet_write_string(worksheet, rowA, 8, [[NSString stringWithFormat:@"%.2lf",realPrice] UTF8String], columnTitleformat);
    
    
    int  rowB = 4 + (int)self.accountDataArray.count;
    // 合并單元格。rowB行0列 到 rowB行1列合并為一行,并設(shè)定內(nèi)容為 "負(fù)責(zé)人:"
    worksheet_merge_range(worksheet, rowB,  0 ,rowB, 1, [@"負(fù)責(zé)人:" cStringUsingEncoding:NSUTF8StringEncoding], columnTitleformat);
    // 合并單元格。rowB行3列 到 rowB行4列合并為一行,并設(shè)定內(nèi)容為 "填表人:"
    worksheet_merge_range(worksheet, rowB,  3 ,rowB, 4, [@"填表人:" cStringUsingEncoding:NSUTF8StringEncoding], columnTitleformat);
    // 合并單元格。rowB行6列 到 rowB行7列合并為一行,并設(shè)定內(nèi)容為 "單位:(蓋章)"
    worksheet_merge_range(worksheet, rowB,  6 ,rowB, 7, [@"單位:(蓋章)" cStringUsingEncoding:NSUTF8StringEncoding], columnTitleformat);
    // 第rowB行的高度為50,并將格式2應(yīng)用到該行上。注意 行的高度和列表的寬度的值單位不一樣,此50非彼50
    worksheet_set_row(worksheet, rowB, 50, columnTitleformat);
    
    // 格式3
    lxw_format *markformat = workbook_add_format(workbook);
    // 內(nèi)容垂直居中
    format_set_align(markformat, LXW_ALIGN_VERTICAL_CENTER);
    // 內(nèi)容水平居中
    format_set_align(markformat, LXW_ALIGN_CENTER);
    // 字體尺寸
    format_set_font_size(markformat, 17);
    // 字體顏色
    format_set_font_color(markformat,0xFF0000);
    int  rowC = 5 + (int)self.accountDataArray.count;
    // 合并單元格。rowC行0列 到 rowB行8列合并為一行,并設(shè)定內(nèi)容為 "備注1、使用文化和旅游惠民消費(fèi)券的訂單,以通聯(lián)訂單號(hào)為唯一標(biāo)識(shí)逐筆填寫(xiě)。"
    worksheet_merge_range(worksheet, rowC,  0 ,rowC, 8, [@"備注1、使用文化和旅游惠民消費(fèi)券的訂單,以通聯(lián)訂單號(hào)為唯一標(biāo)識(shí)逐筆填寫(xiě)。" cStringUsingEncoding:NSUTF8StringEncoding], markformat);
    // 第rowC行的高度為50,并將格式3應(yīng)用到該行上。注意 行的高度和列表的寬度的值單位不一樣,此30非彼30
    worksheet_set_row(worksheet,  rowC, 30, markformat);
    
    
    // 遍歷數(shù)據(jù)源,將表格數(shù)據(jù)寫(xiě)入到某行某列中
    for (int i = 0; i < self.accountDataArray.count; i++) {
        ZB_AccountModel *model = self.accountDataArray[i];
        NSString *calTime  = [FYTimeManager timeWithDataTime:model.paymentTime/1000];
        worksheet_set_row(worksheet, 3+i, 30, columnTitleformat);
        worksheet_write_string(worksheet, 3+i, 0, [[NSString stringWithFormat:@"%d",i+1] UTF8String], columnTitleformat);
        worksheet_write_string(worksheet, 3+i, 1, [model.companyName UTF8String], columnTitleformat);
        worksheet_write_string(worksheet, 3+i, 2, [model.accountNo UTF8String], columnTitleformat);
        worksheet_write_string(worksheet, 3+i, 3, [calTime UTF8String], columnTitleformat);
        worksheet_write_string(worksheet, 3+i, 4, [model.orderNo UTF8String], columnTitleformat);
        worksheet_write_string(worksheet, 3+i, 5, [model.price UTF8String], columnTitleformat);
        worksheet_write_string(worksheet, 3+i, 6, [model.allInPayOrderNo UTF8String], columnTitleformat);
        worksheet_write_string(worksheet, 3+i, 7, [model.discountMoney UTF8String], columnTitleformat);
        worksheet_write_string(worksheet, 3+i, 8, [model.payment UTF8String], columnTitleformat);
    }
    //保存
    workbook_close(workbook);
}

// 導(dǎo)出按鈕點(diǎn)擊
-(void)exportAccountClick:(UIButton *)btn{
    // 獲取cache路徑
    NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSLog(@"documentDirectory為%@",documentDirectory);
    NSString *xlsxName = [NSString stringWithFormat:@"%ld年%ld月%ld日-%ld年%ld月%ld日對(duì)賬單.xlsx",self.startYear,self.startMonth,self.startDay,self.endYear,self.endMonth,self.endDay];
    // 拼接 cache路徑 + 名為xlsxName的文件。注意:注意filename一定要和當(dāng)初創(chuàng)建時(shí)的文件名保持一致,否則讀取不到該文件
    NSString *filename = [documentDirectory stringByAppendingPathComponent:xlsxName];
    // 初始化并讀取路徑為filename的文件
    self.document = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filename]];
    self.document.delegate = self;
    // 以present的方式展示該文件所支持的第三方App列表
    [self.document presentOpenInMenuFromRect:self.view.bounds inView:self.view animated:YES];
}


#pragma mark - documentDelegate

-(UIViewController*)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController*)controller{
    
    return self;
    
}

- (UIView*)documentInteractionControllerViewForPreview:(UIDocumentInteractionController*)controller {
    
    return self.view;
    
}

- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController*)controller {
    
    return self.view.frame;
    
}

//點(diǎn)擊預(yù)覽窗口的“Done”(完成)按鈕時(shí)調(diào)用
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController*)controller {
    
}

// 文件分享面板彈出的時(shí)候調(diào)用
- (void)documentInteractionControllerWillPresentOpenInMenu:(UIDocumentInteractionController*)controller{
    
    NSLog(@"WillPresentOpenInMenu");
    
}

// 當(dāng)選擇一個(gè)文件分享App的時(shí)候調(diào)用
- (void)documentInteractionController:(UIDocumentInteractionController*)controller willBeginSendingToApplication:(nullable NSString*)application{
    
    NSLog(@"begin send : %@", application);
    
}

// 彈框消失的時(shí)候走的方法
-(void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController*)controller{
    
    NSLog(@"dissMiss");
    
}

@end

效果

  • 使用的UITableview做的效果


    image.png
  • 導(dǎo)出按鈕點(diǎn)擊,彈出可以支持該文件的三方App


    image.png
  • excel導(dǎo)出發(fā)送到App中


    image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容