前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实践-佳博蓝牙打印机打印实现

实践-佳博蓝牙打印机打印实现

作者头像
進无尽
发布2018-09-12 18:29:11
3.7K0
发布2018-09-12 18:29:11
举报
文章被收录于专栏:進无尽的文章進无尽的文章

前言

最近项目中使用到了打印机,最后总算打印出自己想要打印的数据了,还算不错,做一个小结吧,希望对需要的朋友有些帮助。


打印机

我们使用的打印机是 《佳博ZH3080条码打印蓝牙标签机.....》,特殊说明一下,我使用的是标签模式(有标签模式和小票模式),而且使用标签模式的时候,如果打印机中的纸比较窄的话,每次打印,打印机都会回退纸张,这样就无法使用了,因为每次都是贴着边缘撕的纸,回退的话,纸就出不来了。必须选用宽大的纸,我使用的纸大概宽度有8CM

效果

工程设置

不设置会直接Crash

Paste_Image.png

步骤

  • 链接上打印机
  • 组装要打印的数据
  • 设置打印机参数
  • 执行打印

步骤解析和源码示例

链接打印机

打印机SDK头文件.png

代码语言:javascript
复制
# ConnectViewController是Dome中提供的 带有 xib的链接类,继承自  CBController。CBController 的实现文件 .m是封装到SDK中的,我们不得而知,但是这里用到继承是为了 获取CBController 的方法和全局变量,下面会解释
@interface ConnectViewController : CBController

#CBController 的代理方法,
************************************************************

#[self startScan]; 调用后会返回这个方法,在这个方法中刷新列表,而且数据都在  CBController 的中  devicesList  中返回所有搜素到的设备
- (void)updateDiscoverPeripherals {
    [super updateDiscoverPeripherals];
    [devicesTableView reloadData];
}
#断开一个打印机,会触发这个代理方法来通知子类,
- (void)updateMyPeripheralForDisconnect:(MyPeripheral *)myPeripheral {
   
}
#链接一个打印机,会触发这个代理方法来通知子类,
- (void)updateMyPeripheralForNewConnected:(MyPeripheral *)myPeripheral {
}
*************************************************************
- (void)viewDidAppear:(BOOL)animated {
        [self startScan];
 }
 
#这个方法会执行  CBController 中搜索附近打印机设备的方法,并且以代理updateDiscoverPeripherals的方法把结果放到 devicesList中
- (void)startScan {
    [super startScan];
}

# 在表的  numberOfRowsInSection  方法中过滤掉未识别的设备
 for (MyPeripheral *tmpPeripheral in devicesList) {
     if (!tmpPeripheral.advName) {
        [devicesList removeObject:tmpPeripheral];
       }
 }
return [devicesList count];

组装要打印的数据

代码语言:javascript
复制
 #最终的效果如下
 NSArray *textArray = @[@"领料单详情",
                           @"领料人:张笑傲",
                           @"2016-12-16",
                           @"----------------------------------",
                           @"商品名称     数量      单位",
                           @"西瓜         11        斤",
                           @"(领取生产日期为,\n严格核对严格核对严格核对)",
                           @"西瓜         11        斤",
                           @"(领取生产日期为,严格\n核对严格核对严格核对)",
                           @"西瓜         11        斤",
                           @"(领取生产日期为,严格核\n对严格核对严格核对)",
                           @"西瓜         11        斤",
                           @"(领取生产日期为,严格核对严格核对严格核对)",
                           @"西瓜         11        斤",
                           @"(领取生产日期为,严格核对严格核对严格核对)",
                           @"-----------------------------------",
                           @"商品种类数:5",];


#根据一个字典,组装数据
- (void)initPrintStrWith :(NSDictionary *)dataDic;
  {
    [printStrArray removeAllObjects];
    [printStrArray addObject:@"领料单详情"];
    [printStrArray addObject:[NSString stringWithFormat:@"领料人:%@",dataDic[@"cgd"][@"zdperson"]]];
    [printStrArray addObject:dataDic[@"cgd"][@"lldate"]];
    [printStrArray addObject:@"--------------------------------------"];
    [printStrArray addObject:[self getPrintString:@"商品名称" :@"数量" tail:@"单位"]];
    NSArray *listArray = dataDic[@"xqlist"];
    for (int i = 0; i<listArray.count; i++) {
        NSDictionary *dic = listArray[i];
        NSString *name = dic[@"hpname"];
        NSString *numer = [dic[@"hpnumber"] stringValue];
        NSString *danwei = dic[@"dwname"];
        #组成固定长度的字符串,中间填充 空格
        NSString *inforStr = [self getPrintString:name :numer tail:danwei];
        [printStrArray addObject:inforStr];
        if ([self recursionSubStr:dic[@"hpscrq"]]) {
            #递归的方法截字符串
            [printStrArray addObjectsFromArray:[self recursionSubStr:[dic[@"hpscrq"] stringByReplacingOccurrencesOfString:@"#" withString:@""]]];
        }
    }
    [printStrArray addObject:@"--------------------------------------"];
    [printStrArray addObject:[NSString stringWithFormat:@"商品种类数:%lu",(unsigned long)listArray.count]];
    
}

#判断中英混合的的字符串长度,
#如果你的打印效果是同一种类型的文字当然可以,但如果同时包含字母,汉子,数字等,那么用length计算的长度就不准确了,因为字母,汉子的编码不同,字节数是不同的,所以要转换成Unicode编码统一的计算。**
- (int)convertToInt:(NSString*)strtemp
{
    int strlength = 0;
    char* p = (char*)[strtemp cStringUsingEncoding:NSUnicodeStringEncoding];
    for (int i=0 ; i<[strtemp lengthOfBytesUsingEncoding:NSUnicodeStringEncoding] ;i++) {
        if (*p) {
            p++;
            strlength++;
        }
        else {
            p++;
        }
    }
    return strlength;
}
#三部分数据拼成固定长度Str     中间填充空格组装成固定长度的字符串
- (NSString *)getPrintString:(NSString *)leader  :(NSString *)middle    tail:(NSString *)tail
{
    static int TOTAL = 30;//这里是根据你的纸张宽度试验出来的一个合适的总字数
    
    NSMutableString *printString = [NSMutableString new];
    [printString appendString:leader];
    int lenderLen = [self convertToInt:leader];
    
    if (tail && middle) {
        int midddleLen = [self convertToInt:middle];
        int tailLen = [self convertToInt:tail];
        
        int detal = (int)(TOTAL - lenderLen - tailLen - midddleLen)/2;
        for (int i = 0; i < detal; i ++) {
            [printString appendString:@" "];
        }
        [printString appendString:middle];
        for (int i = 0; i < detal; i ++) {
            [printString appendString:@" "];
        }
        [printString appendString:tail];
    }
    return printString;
}
#递归的方法分割字符串,     把比较长的字符串截成几段固定长度的字符串后放入数组中
- (NSArray *)recursionSubStr:(NSString *)origaneStr
{
    
    NSMutableArray *strA = [[NSMutableArray alloc]initWithCapacity:0];
    if (origaneStr.length<30) {
        [strA addObject:origaneStr];
        return strA;   
    }
    [strA addObject:[origaneStr substringToIndex:29]];
    [strA  addObjectsFromArray:[self recursionSubStr:[origaneStr substringFromIndex:29]]];
    return strA;
}

设置打印机参数

代码语言:javascript
复制
- (void)printAction;
{
    if (printStrArray.count==0) {
        return;
    }
    
    TscCommand *tscCmd = [[TscCommand alloc] init];
    #设置为YES才能打印
    [tscCmd setHasResponse:YES];
    #设置打印纸的打印尺寸  从打印纸的右边开始计算宽度 设置的尺寸要小于实际的宽度才能在左边留白   高度为打印区域的高度     都是 mm 单位,尺寸为实际打印出的尺寸(可以用尺子测量)
    [tscCmd addSize:73 :((int)(printStrArray.count+3)*3+10)];
    #设置标签间隙尺寸  没什么用
    [tscCmd addGapWithM:10   withN:10];
    #不设置会有异常,不设置第一次打印出现很大的空白空隙
    [tscCmd addReference:10
                        :10];
    #打印速度
    [tscCmd addSpeed:4];
    [tscCmd addDensity:8];
    #0正向  1反向(尾部的先打印出来)
    [tscCmd addDirection:0];
    [tscCmd addComonCommand];
    [tscCmd addCls];
    # x,y 值   目测是  1/100 厘米  x,从左到右依次增大,y从上到下依次增大
    NSMutableArray *xArray = [[NSMutableArray alloc]initWithCapacity:0];
    for (int i = 0; i<printStrArray.count; i++) {
        if (i==0) {
            [xArray addObject:@"200"];
        }else{
            [xArray addObject:@"0"];
        }
    } 
    #设置每条要打印的字符串的 x,y 值
    for (int i=0; i<printStrArray.count;i++) {
        
        [tscCmd addTextwithX:[xArray[i] intValue]
                       withY:(i*30)
                    withFont:@"TSS24.BF2"
                withRotation:0
                   withXscal:1
                   withYscal:1
                    withText:printStrArray[i]];
    }
    #打印二维码
    [tscCmd addQRCode:380
                     :(15)
                     :@"L"
                     :4
                     :@"A"
                     :0
                     :allDataDic[@"cgd"][@"ewmcode"]];
    
    #不在最后打印 .  底部留白太少,撕下来时会撕不完整,打印一个  .  在底部即可达到底部留白的效果,
    #而且有时候,不在最后打印  .\n  很多内容打印不出来,不知道为什么。
    [tscCmd addTextwithX:20
                   withY:((int)(printStrArray.count)*30+5)
                withFont:@"TSS24.BF2"
            withRotation:0
               withXscal:1
               withYscal:1
                withText:@".\n"];

    #print 执行打印命令
    [tscCmd addPrint:1 :1];
}

执行打印

代码语言:javascript
复制
 //打印操作
 - (void)NewRightNavItemClick
  {
    
    if([[BLKWrite Instance] isConnecting]){
       [printManager initPrintStrWith:intBackDic :YES];
       [printManager printAction];
    }
    else{
        [[BLKWrite Instance] setBWiFiMode:NO];
        [self.navigationController pushViewController:[[ConnectViewController alloc] initWithNibName:nil bundle:nil] animated:YES];
      
    **************************************************************
    #这里有一个值得注意的地方,如果链接了打印机,还想点击进入链接页面,展示出链接的打印机信息,需要使用下面的方法,
    #即进入上次创建的哪个视图,不能新建,新建的话会遇到SDK报错Alert弹框。这里是用了单例保存了上次新建的链接视图。
    // [[BLKWrite Instance] setBWiFiMode:NO];
    // AppDelegate *dele = [UIApplication sharedApplication].delegate;
    // [self.navigationController pushViewController:dele.mConnBLE animated:YES];
     #AppDelegate中
     @property (strong, nonatomic) ConnectViewController *mConnBLE;
     self.mConnBLE = [[ConnectViewController alloc] initWithNibName:nil bundle:nil];
    }
}

有帮助的文章 iOS中的蓝牙开发 iOS蓝牙原生封装,助力智能硬件开发

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.01.10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 打印机
  • 效果
  • 工程设置
  • 步骤
  • 步骤解析和源码示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档