在 PDF 中显示 UTF-8 字符

The*_*elf 3 javascript pdf utf-8 character-encoding sap-basis

我试图通过从后端将 PDF 转换为二进制字符串来显示 PDF。这是我正在进行的 ajax 调用

    $.ajax({
        type : 'GET',
        url : '<url>',          
        data : oParameters,
        contentType : 'application/pdf;charset=UTF-8',
        success : function(odata) {

            window.open("data:application/pdf;charset=utf-8," + escape(odata));
Run Code Online (Sandbox Code Playgroud)

} });

当我尝试在新窗口中打开 PDF 时,网址看起来像

数据:应用程序/pdf;字符集=utf-8,%25PDF-1.3%0D%0A%25%uFFFD%uFFFD%uFFFD%uFFFD%0D%0A2%200%20obj%0D%0A/WinAnsiEncoding%0D... ....

如您所见,它使用“WinAnsiEncoding”来显示 PDF。因此,某些字符无法正确显示。如何将其更改为 UTF-8?

编辑:后端在ABAP中。我正在使用功能模块“CONVERT_OTF”将 smartform 转换为 OTF,然后转换为字符串。

           CALL FUNCTION fname
         EXPORTING
           user_settings      = space
           control_parameters = ls_ctropt
           output_options     = ls_output
           gv_lang            = lv_lang
         IMPORTING
           job_output_info    = ls_body_text
         EXCEPTIONS
           formatting_error   = 1
           internal_error     = 2
           send_error         = 3
           user_canceled      = 4
           OTHERS             = 5.

CALL FUNCTION 'CONVERT_OTF'
          EXPORTING
             format                = 'PDF' 
          IMPORTING
           bin_filesize          = ls_pdf_len
           bin_file              = ls_pdf_xstring
          TABLES
             otf                   = ls_body_text-otfdata
             lines                 = lt_lines
           EXCEPTIONS
             err_max_linewidth     = 1
             err_format            = 2
             err_conv_not_possible = 3
             err_bad_otf           = 4
             OTHERS                = 5.
   CALL METHOD server->response->set_header_field( name = 'Content-Type'
     value = 'application/pdf;charset=UTF-8' ).
   CALL METHOD server->response->append_data( data = lv_pdf_string
     length = lv_len ).
Run Code Online (Sandbox Code Playgroud)

mkl*_*mkl 6

关于您说它使用“WinAnsiEncoding”来显示 PDF 的评论:

逗号之后

data:application/pdf;charset=utf-8,%25PDF-1.3%0D%0A%25%uFFFD%uFFFD%uFFFD%uFFFD%0D%0A2%200%20obj%0D%0A/WinAnsiEncoding%0D........
Run Code Online (Sandbox Code Playgroud)

一切都是纯粹的数据。因此,“WinAnsiEncoding”只是PDF内容的一部分,如果这是您遇到麻烦的原因,则必须要求PDF生成器更改其PDF生成过程。

在当前的情况下,您的数据是:

%PDF-1.3
%...
2 0 obj
/WinAnsiEncoding
........
Run Code Online (Sandbox Code Playgroud)

这是完全正常的 PDF 结构。它仅仅意味着 PDF 对象 2 被定义为/WinAnsiEncoding可能会或可能不会用于某些字体定义,即使使用它,它仍然可以通过某些/差异进行调整以包含您需要的字符。此外,将其更改为 UTF-8 (按照您的要求)是没有意义的,因为 UTF-8 不是 PDF 页面内容的标准编码。如果你以某种方式放在UTF-8那里,你会进一步破坏 PDF。

但我担心还存在其他问题。

  1. 您将字符集参数添加到类型application/pdf --- 这没有意义,PDF 是二进制格式,即需要字节序列,因此不涉及字符集。

  2. 您的方法调用escape(odata)创建%uFFFD%uFFFD%uFFFD%uFFFD --- 根据仅定义的 RFC,这是无效的

    当八位位组的相应字符位于允许的集合之外或者用作组件的分隔符或在组件内时,百分比编码机制用于表示组件中的数据八位位组。百分比编码的八位字节被编码为字符三元组,由百分号字符“%”后跟表示该八位字节数值的两个十六进制数字组成。

    RFC 3986,第 2.1 节)

    由于百分号 (“%”) 字符用作百分比编码八位字节的指示符,因此必须将其百分比编码为“%25”,该八位字节才能用作 URI 中的数据。

    同上,第 2.4 节)

    因此,%uFFFD%uFFFD%uFFFD%uFFFD无效。

  3. PDF 作为二进制格式更适合 Base64 编码,即

    data:application/pdf;base64,BASE_64_ENCODED_PDF
    
    Run Code Online (Sandbox Code Playgroud)

    因此,我建议您相应地更改客户端流程。