让Fastreport3.x支持中文PDF的输出

2016-02-19 20:49 100 1 收藏

今天图老师小编给大家展示的是让Fastreport3.x支持中文PDF的输出,精心挑选的内容希望大家多多支持、多多分享,喜欢就赶紧get哦!

【 tulaoshi.com - 编程语言 】

  转自大富翁论坛,至于如何重新编译可以参考《Fastreport 3.07 专业的安装及中文化》

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  Q:FastReport 3.x导出PDF乱码怎么解决?(中文乱码,英文没问题).
  A:用下面这代码替换 frxPDFFile.pas 中原来的代码就可以了
  已在enterprise(应该说是professional) 3.07下测试通过;
  注意事项:字体内嵌的复选框不可选。

  procedure TfrxPDFFont.SaveToStream(Stream: TStream);
  var
    s: String;
    b: TBitmap;
    pm: ^OUTLINETEXTMETRIC;
    FontName: String;
    i: Cardinal;
    pfont: PChar;
    FirstChar, LastChar : Integer;
    MemStream: TMemoryStream;
    MemStream1: TMemoryStream;
    pwidths: PABC;
    Charset: TFontCharSet;

    // support DBCS font name encoding
    function EncodeFontName(AFontName: String): string;
    var
      s: string;
      Index, Len: Integer;
    begin
      // Add Begin by ijia 2004.12.20
      // 修正在简体系统下繁体字体名的问题
      // 只提供 MingLiU, PMingLiU -- 细明体, 新细明体的修正
      s:=UpperCase(AFontName);
      if Copy(s, 1, 7)='MINGLIU' then
        AFontName:='细明体';
     
      if Copy(s, 1, 8)='PMINGLIU' then
        AFontName:='新细明体';
      // Add end
      s := '';
      Len := Length(AFontName);
      Index := 0;
      while Index Len do
      begin
        Index := Index + 1;
        if Byte(AFontName[Index]) $7F then
          s := s + '#' + IntToHex(Byte(AFontName[Index]), 2)
        else
          s := s + AFontname[Index];
      end;
      Result := s;
    end;

  begin
    inherited SaveToStream(Stream);
    b := TBitmap.Create;
    b.Canvas.Font.Assign(Font);
    b.Canvas.Font.Size := 750;
    i := GetOutlineTextMetrics(b.Canvas.Handle, 0, nil);
    GetMem(pm, i);
    GetOutlineTextMetrics(b.Canvas.Handle, i, pm);
    FirstChar := Ord(pm.otmTextMetrics.tmFirstChar);
    LastChar := Ord(pm.otmTextMetrics.tmLastChar);
    FontName := StringReplace(Font.Name, ' ', '#20', [rfReplaceAll]);
    s := '';
    if fsBold in Font.Style then
      s := s + 'Bold';
    if fsItalic in Font.Style then
      s := s + 'Italic';
    if s '' then
      FontName := FontName + ',' + s;

    Charset := pm.otmTextMetrics.tmCharSet;
    // Add by ijia 2004.12.20
    //if Charset = CHINESEBIG5_CHARSET then
    if Charset in [CHINESEBIG5_CHARSET, GB2312_CHARSET] then
      FontName := EncodeFontName(FontName)
    else
      FontName := Parent.PTool.PrepareString(FontName);

    Parent.XRefAdd(Stream);
    WriteLn(Stream, IntToStr(Index + Parent.FStartFonts) + ' 0 obj');
    WriteLn(Stream, '');
    WriteLn(Stream, '/Type /Font');
    WriteLn(Stream, '/Name /F' + IntToStr(Index - 1));
    WriteLn(Stream, '/BaseFont /' + EncodeFontName(FontName));

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

    // Add by ijia 2004.12.20
    //if Charset CHINESEBIG5_CHARSET then
    if not (Charset in [CHINESEBIG5_CHARSET, GB2312_CHARSET]) then
      WriteLn(Stream, '/Subtype /TrueType')
    else
      WriteLn(Stream, '/Subtype /Type0');

    case Charset of
      SYMBOL_CHARSET, ANSI_CHARSET:
        WriteLn(Stream, '/Encoding /WinAnsiEncoding');

      RUSSIAN_CHARSET: {1251}
      begin
        WriteLn(Stream, '/Encoding /Type/Encoding /BaseEncoding /WinAnsiEncoding');
        Write(Stream, '/Differences [129 /afii10052');
        Write(Stream, '/quotesinglbase/afii10100/quotedblbase/ellipsis/dagger/daggerdbl/Euro/perthousand/afii10058/guilsinglleft/afii10059/afii10061/afii10060/afii10145/afii10099/quoteleft');
        Write(Stream, '/quoteright/quotedblleft/quotedblright/bullet/endash/emdash/space/trademark/afii10106/guilsinglright/afii10107/afii10109/afii10108/afii10193/space/afii10062');
        Write(Stream, '/afii10110/afii10057/currency/afii10050/brokenbar/section/afii10023/copyright/afii10053/guillemotleft/logicalnot/hyphen/registered/afii10056/degree/plusminus');
        Write(Stream, '/afii10055/afii10103/afii10098/mu/paragraph/periodcentered/afii10071/afii61352/afii10101/guillemotright/afii10105/afii10054/afii10102/afii10104/afii10017/afii10018');
        Write(Stream, '/afii10019/afii10020/afii10021/afii10022/afii10024/afii10025/afii10026/afii10027/afii10028/afii10029/afii10030/afii10031/afii10032/afii10033/afii10034/afii10035');
        Write(Stream, '/afii10036/afii10037/afii10038/afii10039/afii10040/afii10041/afii10042/afii10043/afii10044/afii10045/afii10046/afii10047/afii10048/afii10049/afii10065/afii10066');
        Write(Stream, '/afii10067/afii10068/afii10069/afii10070/afii10072/afii10073/afii10074/afii10075/afii10076/afii10077/afii10078/afii10079/afii10080/afii10081/afii10082/afii10083');
        WriteLn(Stream, '/afii10084/afii10085/afii10086/afii10087/afii10088/afii10089/afii10090/afii10091/afii10092/afii10093/afii10094/afii10095/afii10096/afii10097/space]');
        WriteLn(Stream, '');
      end;

      EASTEUROPE_CHARSET: {1250}
      begin
        WriteLn(Stream, '/Encoding /Type/Encoding /BaseEncoding /WinAnsiEncoding');
        Write(Stream, '/Differences [128 /Euro 140 /Sacute /Tcaron /Zcaron /Zacute');
        Write(Stream, ' 156 /sacute /tcaron /zcaron /zacute 161 /caron /breve /Lslash');
        Write(Stream, ' 165 /Aogonek 170 /Scedilla 175 /Zdotaccent 178 /ogonek /lslash');
        Write(Stream, ' 185 /aogonek /scedilla 188 /Lcaron /hungarumlaut /lcaron /zdotaccent /Racute');
        Write(Stream, ' 195 /Abreve 197 /Lacute /Cacute 200 /Ccaron 202 /Eogonek 204 /Ecaron 207 /Dcaron /Dslash');
        Write(Stream, ' 209 /Nacute /Ncaron /Oacute 213 /Ohungarumlaut 216 /Rcaron /Uring 219 /Uhungarumlaut');
        Write(Stream, ' 222 /Tcedilla 224 /racute 227 /abreve 229 /lacute /cacute /ccedilla /ccaron');
        Write(Stream, ' 234 /eogonek 236 /ecaron 239 /dcaron /dmacron /nacute /ncaron 245 /ohungarumlaut');
        Write(Stream, ' 248 /rcaron /uring 251 /uhungarumlaut 254 /tcedilla /dotaccent]');
        WriteLn(Stream, '');
      end;

      TURKISH_CHARSET,
      GREEK_CHARSET,
      HEBREW_CHARSET,
      ARABIC_CHARSET,
      VIETNAMESE_CHARSET:
      begin
        WriteLn(Stream, '/Encoding /Type/Encoding /BaseEncoding /WinAnsiEncoding');
        Write(Stream, '/Differences [128 /Euro 142 /Zcaron 158 /zcaron]');
        WriteLn(Stream, '');
      end;

      CHINESEBIG5_CHARSET: {136}
      begin
        WriteLn(Stream, '/DescendantFonts [' + IntToStr(Index + 1 + Parent.FStartFonts) + ' 0 R]');
        WriteLn(Stream, '/Encoding /ETenms-B5-H');
        WriteLn(Stream, '');
        WriteLn(Stream, 'endobj');

        WriteLn(Stream, IntToStr(Index + 1 + Parent.FStartFonts) + ' 0 obj');
        WriteLn(Stream, '');
        WriteLn(Stream, '/Type /Font');
        WriteLn(Stream, '/Subtype');
        WriteLn(Stream, '/CIDFontType2');
        WriteLn(Stream, '/BaseFont /'+ EncodeFontName(FontName));
        WriteLn(Stream, '/WinCharSet 136');
        WriteLn(Stream, '/FontDescriptor ' + IntToStr(Index + 2 + Parent.FStartFonts) + ' 0 R');
        WriteLn(Stream, '/CIDSystemInfo');
        WriteLn(Stream, '');
        WriteLn(Stream, '/Registry(Adobe)');
        WriteLn(Stream, '/Ordering(CNS1)');
        WriteLn(Stream, '/Supplement 0');
        WriteLn(Stream, '');
        WriteLn(Stream, '/DW 1000');
        WriteLn(Stream, '/W [1 95 500]');
        WriteLn(Stream, '');
        WriteLn(Stream, 'endobj');

        Parent.XRefAdd(Stream);

        WriteLn(Stream, IntToStr(Index + 2 + Parent.FStartFonts) + ' 0 obj');
        WriteLn(Stream, '');
        WriteLn(Stream, '/Type /FontDescriptor');
        if Parent.FEmbedded then
           WriteLn(Stream, '/FontFile2 ' + IntToStr(Index + 4 + Parent.FStartFonts) + ' 0 R');
        WriteLn(Stream, '/FontName /' + EncodeFontName(FontName));
        WriteLn(Stream, '/Flags 7');
        WriteLn(Stream, '/FontBBox [' + IntToStr(pm^.otmrcFontBox.Left) + ' '+ IntToStr(pm^.otmrcFontBox.Bottom) + ' '+ IntToStr(pm^.otmrcFontBox.Right) + ' '+ IntToStr(pm^.otmrcFontBox.Top) + ' ]');
        WriteLn(Stream, '/Style /Panose 010502020300000000000000 ');
        WriteLn(Stream, '/Ascent ' + IntToStr(pm^.otmAscent));
        WriteLn(Stream, '/Descent ' + IntToStr(pm^.otmDescent));
        WriteLn(Stream, '/CapHeight ' + IntToStr(pm^.otmTextMetrics.tmHeight));
        WriteLn(Stream, '/StemV ' + IntToStr(50 + Round(sqr(pm^.otmTextMetrics.tmWeight / 65))));
        WriteLn(Stream, '/ItalicAngle ' + IntToStr(pm^.otmItalicAngle));
        WriteLn(Stream, '');
        WriteLn(Stream, 'endobj');
      end;
     
      // Add begin by ijia 2004.12.20
      GB2312_CHARSET: {134}
      begin
        WriteLn(Stream, '/DescendantFonts [' + IntToStr(Index + 1 + Parent.FStartFonts) + ' 0 R]');
        WriteLn(Stream, '/Encoding /GB-EUC-H');
        WriteLn(Stream, '');
        WriteLn(Stream, 'endobj');

        WriteLn(Stream, IntToStr(Index + 1 + Parent.FStartFonts) + ' 0 obj');
        WriteLn(Stream, '');
        WriteLn(Stream, '/Type /Font');
        WriteLn(Stream, '/Subtype');
        WriteLn(Stream, '/CIDFontType2');
        WriteLn(Stream, '/BaseFont /'+ EncodeFontName(FontName));
        WriteLn(Stream, '/WinCharSet 134');
        WriteLn(Stream, '/FontDescriptor ' + IntToStr(Index + 2 + Parent.FStartFonts) + ' 0 R');
        WriteLn(Stream, '/CIDSystemInfo');
        WriteLn(Stream, '');
        WriteLn(Stream, '/Registry(Adobe)');
        WriteLn(Stream, '/Ordering(GB1)');
        WriteLn(Stream, '/Supplement 2');
        WriteLn(Stream, '');
        WriteLn(Stream, '/DW 1000');
        WriteLn(Stream, '/W [ 1 95 500 814 939 500 7712 [ 500 ] 7716 [ 500 ] ]');
        WriteLn(Stream, '');
        WriteLn(Stream, 'endobj');

        Parent.XRefAdd(Stream);

        WriteLn(Stream, IntToStr(Index + 2 + Parent.FStartFonts) + ' 0 obj');
        WriteLn(Stream, '');
        WriteLn(Stream, '/Type /FontDescriptor');
        if Parent.FEmbedded then
           WriteLn(Stream, '/FontFile2 ' + IntToStr(Index + 4 + Parent.FStartFonts) + ' 0 R');
        WriteLn(Stream, '/FontName /' + EncodeFontName(FontName));
        WriteLn(Stream, '/Flags 6');
       
        WriteLn(Stream, '/FontBBox [-25 -254 1000 880]');
        WriteLn(Stream, '/Style /Panose 010502020400000000000000 ');
        WriteLn(Stream, '/Ascent 880');
        WriteLn(Stream, '/Descent -120');
        WriteLn(Stream, '/CapHeight 880');
        WriteLn(Stream, '/StemV 93');
        WriteLn(Stream, '/ItalicAngle 0');
        WriteLn(Stream, '');
        WriteLn(Stream, 'endobj');
      end;
      // Add end
    end;

    // Add by ijia 2004.12.20
    //if Charset CHINESEBIG5_CHARSET then
    if not (Charset in [CHINESEBIG5_CHARSET, GB2312_CHARSET]) then
    begin
      WriteLn(Stream, '/FontDescriptor ' + IntToStr(Index + 2 + Parent.FStartFonts) + ' 0 R');
      WriteLn(Stream, '/FirstChar ' + IntToStr(FirstChar));
      WriteLn(Stream, '/LastChar ' + IntToStr(LastChar));
      GetMem(pwidths, SizeOf(ABCArray));
      Write(Stream, '/Widths [');
      GetCharABCWidths(b.Canvas.Handle, FirstChar, LastChar, pwidths^);
      for i := 0 to (LastChar - FirstChar) do
        Write(Stream, IntToStr(pwidths^[i].abcA + Integer(pwidths^[i].abcB) + pwidths^[i].abcC) + ' ');
      WriteLn(Stream, ']');
      FreeMem(pwidths);
      WriteLn(Stream, '');
      WriteLn(Stream, 'endobj');
      Parent.XRefAdd(Stream);
      WriteLn(Stream, IntToStr(Index + 2 + Parent.FStartFonts) + ' 0 obj');
      WriteLn(Stream, '');
      WriteLn(Stream, '/Type /FontDescriptor');
      if Parent.FEmbedded then
        WriteLn(Stream, '/FontFile2 ' + IntToStr(Index + 4 + Parent.FStartFonts) + ' 0 R');
      WriteLn(Stream, '/FontBBox [' + IntToStr(pm^.otmrcFontBox.Left) + ' '+ IntToStr(pm^.otmrcFontBox.Bottom) + ' '+ IntToStr(pm^.otmrcFontBox.Right) + ' '+ IntToStr(pm^.otmrcFontBox.Top) + ' ]');
      WriteLn(Stream, '/FontName /' + FontName);
      WriteLn(Stream, '/Flags 32');
      WriteLn(Stream, '/StemV ' + IntToStr(50 + Round(sqr(pm^.otmTextMetrics.tmWeight / 65))));
      WriteLn(Stream, '/CapHeight ' + IntToStr(pm^.otmTextMetrics.tmHeight));
      WriteLn(Stream, '/Ascent ' + IntToStr(pm^.otmAscent));
      WriteLn(Stream, '/Descent ' + IntToStr(pm^.otmDescent));
      WriteLn(Stream, '/ItalicAngle ' + IntToStr(pm^.otmItalicAngle));
      WriteLn(Stream, '');
      WriteLn(Stream, 'endobj');
    end;

    if Parent.FEmbedded then
    begin
      Parent.XRefAdd(Stream);
      WriteLn(Stream, IntToStr(Index + 4 + Parent.FStartFonts) + ' 0 obj');
      i := GetFontData(b.Canvas.Handle, 0, 0, nil, 1);
      GetMem(pfont, i);
      i := GetFontData(b.Canvas.Handle, 0, 0, pfont, i);
      MemStream := TMemoryStream.Create;
      MemStream.Write(pfont^, i);

      MemStream1 := TMemoryStream.Create;
      frxDeflateStream(MemStream, MemStream1, gzMax);
      WriteLn(Stream, ' /Length ' + IntToStr(MemStream1.Size) + ' /Filter /FlateDecode /Length1 ' + IntToStr(MemStream.Size) + ' ');
      WriteLn(Stream, 'stream');
      Stream.CopyFrom(MemStream1, 0);
      MemStream1.Free;

      MemStream.Free;
      FreeMem(pfont);
      WriteLn(Stream, '');
      WriteLn(Stream, 'endstream');
      WriteLn(Stream, 'endobj');
    end;
    FreeMem(pm);
    b.Free;
  end;
  

来源:http://www.tulaoshi.com/n/20160219/1624611.html

延伸阅读
标签: PHP
  我使用的是FPDF(www.fpdf.org),下载了fpdf类库后,还要使用下面的中文类库才能支持中文,但只能使用一种中文字体(华文仿宋)。为此我烦恼了很长时间,现在终于搞定了,将TrueType字体转化为pt1字体使用: 下面是在FPDF上找的一个中文类库: <?php require('fpdf.php'); $Big5_widths=array(' '=250,'!'=250,'"'=408,'#'=668,'$...
Mac版Skype支持简体中文   Skype昨天针对Mac平台推出了一个新的版本,新版最大的特点就是增加对简体中文的支持,并可以更加方便地新建联系人。 Skype Skype 6.4 for Mac主要更新功能: 新的无限滚动会话; 对会话内搜索系统进行优化; 改进后的文件传输功能,允许重新接受发送给用户的文件; 新的联系...
标签: Web开发
很早以前发现对于一个 html 元素, id 可以是中文的,而且用 getElementById 方法可以正确取到dom 小弟孤陋寡闻,今天才知道 ie居然支持 javascript中文编程 input type=button value="gorush" id="阿舜" script function 阿舜::onclick(){alert(this.value)} //c++风格 ...
标签: 电脑入门
做文字工作,总经常会遇到需要把撰写的文稿输出成PDF的格式,也总会遇到需要阅读和借用一些PDF格式的文件,以往因为PDF是专属格式,需要安装acrobat reader或其他PDF阅读器来阅读此类文档,在工作中来回窗口的切换很是不方便。现在WPS2009在以往输出PDF的基础上又新增了阅读PDF的功能,让我的工作一下子方便轻松了很多。再也不用在电脑中装那么...
---------------- 使用自定义函数 ---------------------------------------- Q: 我怎样添加我的自定义函数? A: 使用 TfrReport.OnUserFunction 事件. 这里有一个简单的例子: procedure TForm1.frReport1UserFunction(const Name: String; p1, p2, p3: Variant; var val: Variant); begin if AnsiCompareTex...

经验教程

377

收藏

55
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部