灰苹果开发蓝牙知识

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

2017-01-10  本文已影响1446人  進无尽

前言

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


打印机

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

效果

工程设置

不设置会直接Crash

Paste_Image.png

步骤

步骤解析和源码示例

链接打印机

打印机SDK头文件.png
# 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];

组装要打印的数据

 #最终的效果如下
 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;
}

设置打印机参数

- (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];
}

执行打印

 //打印操作
 - (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蓝牙原生封装,助力智能硬件开发

上一篇下一篇

猜你喜欢

热点阅读