infoxicator / react-native-star-prnt

React-Native bridge to communicate with Star Micronics Bluetooth/LAN Printers
MIT License
67 stars 65 forks source link

Print HTML Content #4

Closed CHOMNANP closed 4 years ago

CHOMNANP commented 6 years ago

Is there any option that we can print HTML content?

Sam-Hoult commented 6 years ago

@CHOMNANP For me to get HTML to work, it had to go into a web view which was then captures and printed as a raster. I've contacted Star and they don't support it. I don't have an ObjC background but here's what we've got go if it may help you.

Notes: Using old Star SDK to send the raster ReceiptWidth is set at the top of the request (576 for 3" roll)

#pragma mark - receipt printing webview
-(void)captureWebView:(NSString *)htmlString{
    //    Make this smarter based on the logic used in
    self.requestedReceiptPrinter = [self starPrinterForIndentifier];

    if (self.requestedReceiptPrinter) {
        [self loadWebView:htmlString];
    } else {
        [self showStarPrintError:@"Receipt printer not found. Please check your settings"];
        self.requestedReceiptPrinter = nil;
    }
}

-(void)loadWebView:(NSString *)htmlString {
    //-(void)loadWebView:(NSData *)htmlData {

    int receiptWidth = self.printingWidth;
    // Rendering the webview at offscreen x-y coordinates (iPad resolution)
    int largerScreenDimension = 1500;
    UIWebView *webView = [[UIWebView alloc] init];
    webView.contentMode = UIViewContentModeScaleAspectFit;  // scale the content to fit the size of the view by maintaining the aspect ratio.
    webView.frame = CGRectMake(largerScreenDimension, largerScreenDimension, receiptWidth, 5000);

    UIViewController *controller = [UIApplication sharedApplication].keyWindow.rootViewController;
    [controller.view addSubview:webView]; // UIWebViews without an assigned superview don't load ever.
    webView.delegate = self;
    //    [webView loadData:htmlData MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:[NSURL URLWithString:@""]];
    //    [webView loadHTMLString:[htmlString stringByReplacingOccurrencesOfString:@"\n" withString:@"<br/>"] baseURL:nil];
    [webView loadHTMLString:htmlString baseURL:nil];
}

-(void)webViewDidFinishLoad:(UIWebView *)webView {

    NSString *result = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementById('content').offsetHeight;"];
    NSInteger height = [result integerValue];

    // Wait for webview to have fully rendered before dispatching to print
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.05 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self captureWebViewToPrint:height webView:webView];
    });

}

-(void)captureWebViewToPrint:(NSInteger)height webView:(UIWebView*)webView {

    CGSize size = {webView.bounds.size.width, height};
    UIGraphicsBeginImageContext(size);
    [webView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *webViewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [webView removeFromSuperview];
    webView.delegate = nil;

    [self sendImageToPrinter:webViewImage withReceiptWidth:webView.bounds.size.width];
}

-(void)sendImageToPrinter:(UIImage*)imageData withReceiptWidth:(int)width {
    NSMutableData *commandsToPrint = [NSMutableData new];
    SIOStarBitmap *starbitmap = [[SIOStarBitmap alloc] initWithUIImage:imageData :width :false];
    SIORasterDocument *rasterDoc = [[SIORasterDocument alloc] initWithDefaults:RasSpeed_Medium
                                                            endOfPageBehaviour:RasPageEndMode_FeedAndFullCut
                                                        endOfDocumentBahaviour:RasPageEndMode_FeedAndFullCut
                                                                     topMargin:RasTopMargin_Standard
                                                                    pageLength:0
                                                                    leftMargin:0
                                                                   rightMargin:0];
    NSData *shortcommand = [rasterDoc BeginDocumentCommandData];
    [commandsToPrint appendData:shortcommand];
    shortcommand = [starbitmap getImageDataForPrinting:true];
    [commandsToPrint appendData:shortcommand];
    shortcommand = [rasterDoc EndDocumentCommandData];
    [commandsToPrint appendData:shortcommand];
    //    Command to open the cashDrawer
    [commandsToPrint appendBytes:"\x07"
                          length:sizeof("\x07") - 1];
    [SIOPrinterFunctions sendCommand:commandsToPrint portName:self.requestedReceiptPrinter.portName portSettings:self.starPortSettings timeoutMillis:10000];
}

// WORKS WITH mPOP
-(void)sendImageToBluetoothPrinter:(UIImage*)imageData withReceiptWidth:(int)width {
    NSMutableData *commandsToPrint = [NSMutableData new];
    SIOStarBitmap *starbitmap = [[SIOStarBitmap alloc] initWithUIImage:imageData :width :false];
    NSData *shortcommand = [starbitmap getGraphicsDataForPrinting:false];
    [commandsToPrint appendData:shortcommand];

    [SIOPrinterFunctions sendCommand:commandsToPrint portName:self.requestedReceiptPrinter.portName portSettings:self.starPortSettings timeoutMillis:10000];
}
CHOMNANP commented 6 years ago

Thanks @Sam-Hoult, for sharing. This is helpful. I'll update if I manage to print it out.

osama-rizk commented 4 years ago

hello @Sam-Hoult can you please tell me where to put the above obj-c code to print html

CHOMNANP commented 4 years ago

Hi @Osama-Rezk, can you try this out? https://gitlab.com/CHOMNANP/react-native-star-print-example/tree/print

This is my example of the work around.

  1. Render content into view
  2. screen shot the view in image -> save to local storage
  3. Print the content in image format