phin1x / go-ipp

Pure Go IPP library
Apache License 2.0
138 stars 35 forks source link

Printing Excel files and images results in garbled characters. #36

Closed abc56163 closed 1 year ago

abc56163 commented 1 year ago

Hello, I read Excel or image files, then convert them into byte data and place them into the payload. However, when printing, it doesn't produce images or Excel spreadsheets; everything that prints is garbled encoding. How can I resolve this issue?

phin1x commented 1 year ago

Hi, converting file formats is not part of the ipp protocol and so not part of this library. In your case you need a print server like cups which renders the files into printable formats like pcl or postscript.

abc56163 commented 1 year ago

Hello, the process is as follows: I directly use ioutil.ReadFile to read the content of an Excel file, and then pass it to the method below. When printing, it doesn't correctly print out the table; instead, it prints the encoded content of the Excel file, taking up many pages. I've been having trouble understanding the issue, so I'd like to ask for your assistance. Could you help me understand what might be causing this problem? Thank you very much!

func IppPrinter(content []byte, fileName string, copies int, orientation bool) error {
    req := ipp.NewRequest(ipp.OperationPrintJob, 2)
    req.OperationAttributes[ipp.AttributeJobName] = strings.Split(fileName, ".")[0]

    req.OperationAttributes[ipp.AttributeCopies] = copies

    if !orientation {
        req.OperationAttributes[ipp.AttributeOrientationRequested] = 4
    }

    payload, err := req.Encode()

    payload = append(payload, content...)
    if err != nil {
        return err
    }

    httpReq, err := http.NewRequest("POST", config.PrinterHost, bytes.NewReader(payload))
    if err != nil {
        return errors.New("fail:" + err.Error())
    }

    httpReq.Header.Set("Connection", "keep-alive")
    httpReq.Header.Set("Content-Length", strconv.Itoa(len(payload)))
    // httpReq.Header.Add("Content-Length", strconv.Itoa(len(payload)))
    httpReq.Header.Set("Content-Type", ipp.ContentTypeIPP)
    httpReq.Header.Set("User-Agent", "Internet Print Provider")
    httpReq.Header.Del("Accept-Encoding")
    httpReq.Header.Del("Transfer-Encoding")

    httpClient := &http.Client{}

    httpResp, err := httpClient.Do(httpReq)

    if err != nil {
        return errors.New("fail:" + err.Error())
    }

    defer httpResp.Body.Close()

    if httpResp.StatusCode != 200 {
        return errors.New("non 200 response from server")

    }

    resp, err := ipp.NewResponseDecoder(httpResp.Body).Decode(nil)

    println("success")
    if err != nil {
        return errors.New("ipp:" + err.Error())
    }

    if err := resp.CheckForErrors(); err != nil {
        return errors.New("fail:" + err.Error())
    }
    return nil
}
abc56163 commented 1 year ago

go-ipp connects directly to the printer without passing through other servers

phin1x commented 1 year ago

Your problem is to understand what ipp actually is. ipp is only a protocol which describe how to interact with print servers. from wikipedia:

The Internet Printing Protocol (IPP) is a specialized communication protocol for communication between client devices (computers, mobile phones, tablets, etc.) and printers (or print servers). It allows clients to submit one or more print jobs to the network-attached printer or print server, and perform tasks such as querying the status of a printer, obtaining the status of print jobs, or cancelling individual print jobs.

If you send data with ipp you have to make sure that the server side understand the data. in your case you have to look up the supported file formats of your printer. it seams like excel is not a supported file format so you have to convert the excel sheet in a file format which your printer supports before you send it. file conversion is not part of this library as it only implements the ipp protocol and i cannot help you here. most of the printers support pcl and postscript. so you have to lookup a way to convert excel into pcl or postscript first. then you can send the converted data via ipp to your printer.

abc56163 commented 1 year ago

Thanks to your responses, I now know where the problem lies.