java实现PPT转PDF出现中文乱码问题的解决方法

ppt转成pdf,原理是ppt转成图片,再用图片生产pdf,过程有个问题,不管是ppt还是pptx,都遇到中文乱码,编程方框的问题,其中ppt后缀网上随便找就有解决方案,就是设置字体为统一字体,pptx如果页面是一种中文字体不会有问题,如果一个页面有微软雅黑和宋体,就会导致部分中文方框,怀疑是poi处理的时候,只读取第一种字体,所以导致多个中文字体乱码。
百度和谷歌都找了很久,有看到说apache官网有人说是bug,但他们回复说是字体问题,这个问题其实我觉得poi可能可以自己做,读取原来字体设置成当前字体,不过性能应该会有很多消耗,反正我估计很多人跟我一样花费大量时间找解决方案,网上几乎没有现成的方案。自己也是一步步尝试,最终找到解决办法,ppt格式的就不说了网上找得到,pptx后缀的网上我是没找到。
问题前的pptx转成图片:

解决后的pptx转成图片:

解决方法:
读取每个shape,将文字转成统一的字体,网上找到的那段代码不可行,我自己改的方案如下:

for( XSLFShape shape : slide[i].getShapes() ){
     if ( shape instanceof XSLFTextShape ){
      XSLFTextShape txtshape = (XSLFTextShape)shape ;
      System.out.println("txtshape" + (i+1) + ":" + txtshape.getShapeName());
      System.out.println("text:" +txtshape.getText());

      for ( XSLFTextParagraph textPara : txtshape.getTextParagraphs() ){
       List<XSLFTextRun> textRunList = textPara.getTextRuns();
       for(XSLFTextRun textRun: textRunList) {
        textRun.setFontFamily("宋体");
       }
      }
     }
    }

完整代码如下(除了以上自己的解决方案,大部分是stackoverflow上的代码):

public static void convertPPTToPDF(String sourcepath, String destinationPath, String fileType) throws Exception {
  FileInputStream inputStream = new FileInputStream(sourcepath);
  double zoom = 2;
  AffineTransform at = new AffineTransform();
  at.setToScale(zoom, zoom);
  Document pdfDocument = new Document();
  PdfWriter pdfWriter = PdfWriter.getInstance(pdfDocument, new FileOutputStream(destinationPath));
  PdfPTable table = new PdfPTable(1);
  pdfWriter.open();
  pdfDocument.open();
  Dimension pgsize = null;
  Image slideImage = null;
  BufferedImage img = null;
  if (fileType.equalsIgnoreCase(".ppt")) {
   SlideShow ppt = new SlideShow(inputStream);
   inputStream.close();
   pgsize = ppt.getPageSize();
   Slide slide[] = ppt.getSlides();
   pdfDocument.setPageSize(new Rectangle((float) pgsize.getWidth(), (float) pgsize.getHeight()));
   pdfWriter.open();
   pdfDocument.open();
   for (int i = 0; i < slide.length; i++) {

    TextRun[] truns = slide[i].getTextRuns();
    for ( int k=0;k<truns.length;k++){
     RichTextRun[] rtruns = truns[k].getRichTextRuns();
     for(int l=0;l<rtruns.length;l++){
//      int index = rtruns[l].getFontIndex();
//      String name = rtruns[l].getFontName();
      rtruns[l].setFontIndex(1);
      rtruns[l].setFontName("宋体");
     }
    }  

    img = new BufferedImage((int) Math.ceil(pgsize.width * zoom), (int) Math.ceil(pgsize.height * zoom), BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics = img.createGraphics();
    graphics.setTransform(at);

    graphics.setPaint(Color.white);
    graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
    slide[i].draw(graphics);
    graphics.getPaint();
    slideImage = Image.getInstance(img, null);
    table.addCell(new PdfPCell(slideImage, true));
   }
  }
  if (fileType.equalsIgnoreCase(".pptx")) {
   XMLSlideShow ppt = new XMLSlideShow(inputStream);
   pgsize = ppt.getPageSize();
   XSLFSlide slide[] = ppt.getSlides();
   pdfDocument.setPageSize(new Rectangle((float) pgsize.getWidth(), (float) pgsize.getHeight()));
   pdfWriter.open();
   pdfDocument.open();

   for (int i = 0; i < slide.length; i++) {
    for( XSLFShape shape : slide[i].getShapes() ){
     if ( shape instanceof XSLFTextShape ){
      XSLFTextShape txtshape = (XSLFTextShape)shape ;
      // System.out.println("txtshape" + (i+1) + ":" + txtshape.getShapeName());
      //System.out.println("text:" +txtshape.getText());

      for ( XSLFTextParagraph textPara : txtshape.getTextParagraphs() ){
       List<XSLFTextRun> textRunList = textPara.getTextRuns();
       for(XSLFTextRun textRun: textRunList) {
        textRun.setFontFamily("宋体");
       }
      }
     }
    }
    img = new BufferedImage((int) Math.ceil(pgsize.width * zoom), (int) Math.ceil(pgsize.height * zoom), BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics = img.createGraphics();
    graphics.setTransform(at);
    graphics.setPaint(Color.white);
    graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
    slide[i].draw(graphics);

//    FileOutputStream out = new FileOutputStream("src/main/resources/test"+i+".jpg");
//    javax.imageio.ImageIO.write(img, "jpg", out);

    graphics.getPaint();
    slideImage = Image.getInstance(img, null);
    table.addCell(new PdfPCell(slideImage, true));
   }
  }
  pdfDocument.add(table);
  pdfDocument.close();
  pdfWriter.close();
  System.out.println("Powerpoint file converted to PDF successfully");
 }

maven配置:

<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
 <!-- <version>3.13</version> -->
  <version>3.9</version>
 </dependency>
 <dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <!-- <version>3.10-FINAL</version> -->
  <version>3.9</version>
 </dependency>

 <dependency>
   <groupId>com.itextpdf</groupId>
   <artifactId>itextpdf</artifactId>
   <version>5.5.7</version>
 </dependency>

 <dependency>
  <groupId>com.itextpdf.tool</groupId>
  <artifactId>xmlworker</artifactId>
  <version>5.5.7</version>
 </dependency>
 <dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-scratchpad</artifactId>
  <!-- <version>3.12</version> -->
  <version>3.9</version>
 </dependency>

上面就是为大家分享的java实现PPT转PDF出现中文乱码问题的解决方法,希望对大家的学习有所帮助。

(0)

相关推荐

  • java web将数据导出为pdf格式文件代码片段

    此片段达到的效果是:访问此请求,浏览器将打开新的界面并显示pdf文件预览,在文件预览界面可以下载该pdf文件. 1.jsp界面代码 <input type="button" class="btn btn-info" onclick="getVerPdf();" target="_blank" value="导出为pdf文件" /> 2.js代码 function getVerPdf() { wi

  • Java实现Html转Pdf的方法

    本文实例讲述了Java实现Html转Pdf的方法.分享给大家供大家参考.具体如下: package test; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import org.xhtmlrenderer.pdf.ITextFontResolver; import org.xhtmlrenderer.pdf.ITextRenderer; import com.lowagie.

  • Java生成PDF文件的实例代码

    复制代码 代码如下: package com.qhdstar.java.pdf; import java.awt.Color;import java.io.FileOutputStream; import com.lowagie.text.Chapter;import com.lowagie.text.Document;import com.lowagie.text.Font;import com.lowagie.text.FontFactory;import com.lowagie.text.

  • java中输出pdf文件代码分享

    package snake; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowag

  • Java开源工具iText生成PDF简单实例

    iText下载页面: http://sourceforge.net/projects/itext/files/ 1.创建简单的PDF文件 package console.pdf; import java.io.FileNotFoundException; import java.io.FileOutputStream; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com

  • java使用pdfbox操作pdf文件示例

    还有一个用于创建PDF文件的项目----iText. PDFBox下面有两个子项目:FontBox是一个处理PDF字体的java类库:JempBox是一个处理XMP元数据的java类库. 一个简单示例: 要引入pdfbox-app-1.6.0.jar这个包. 复制代码 代码如下: package pdf; import java.io.File;import java.net.MalformedURLException; import org.apache.pdfbox.pdmodel.PDDo

  • java在pdf中生成表格的方法

    1.目标 在pdf中生成一个可变表头的表格,并向其中填充数据.通过泛型动态的生成表头,通过反射动态获取实体类(我这里是User)的get方法动态获得数据,从而达到动态生成表格. 每天生成一个文件夹存储生成的pdf文件(文件夹的命名是年月日时间戳),如:20151110 生成的文件可能在毫秒级别,故文件的命名规则是"到毫秒的时间戳-uuid",如:20151110100245690-ece540e5-7737-4ab7-b2d6-87bc23917c8c.pdf 通过读取properti

  • java控制Pdf自动打印的小例子

    复制代码 代码如下: public byte[] autoPrintPdf(byte[] pdf_byte) { ByteArrayOutputStream bos=null;  try {   PdfReader reader = new PdfReader(pdf_byte);   bos = new ByteArrayOutputStream();   PdfStamper ps = new PdfStamper(reader, bos);   StringBuffer script =

  • 使用java为pdf添加书签的方法(pdf书签制作)

    由于我经常下载一些pdf格式的电子书,有的时候一些好书下载下来没有书签,读起来感觉没有整体的感觉,所以决定自己写一个小工具,将特定格式的文本解析成为书签,然后保存到pdf格式中.整体思路是从豆瓣啊.京东啊.当当啊.亚马逊下面的介绍中可以copy出目录信息,拿<HTTP权威指南>为例:目录的结构如: 复制代码 代码如下: 第1章 HTTP 概述 31.1 HTTP--因特网的多媒体信使 41.2 Web 客户端和服务器 41.3 资源 51.3.1 媒体类型 61.3.2 URI 71.3.3

  • java中pdf转图片的实现方法

    JAVA中实现pdf转图片可以通过第三方提供的架包,这里介绍几种常用的,可以根据自身需求选择使用. 一.icepdf.有收费版和开源版,几种方法里最推荐的.转换的效果比较好,能识别我手头文件中的中文,就是转换后可能字体的关系部分字间距有点宽.因为,字体支持是要收费的,所以转换的图片会带有官方的水印.去水印的方法可以查看另一篇文章:icepdf去水印方法 1.下载icepdf的架包,并导入项目中,这里用到4个,如下: 2.附上代码例子: String filePath = "c:/test.pdf

  • java原装代码完成pdf在线预览和pdf打印及下载

    前提准备: 1. 项目中至少需要引入的jar包,注意版本: a) core-renderer.jar b) freemarker-2.3.16.jar c) iText-2.0.8.jar d) iTextAsian.jar 上代码: 注释: 此类为自定义的Tag类的基类,在action中怎么放的数据,在ftl中就怎么取数据,简洁明了.  1. 自定义Tag类的基类 /** * 通用的生成pdf预览和生成打印的html文件 * * @author xg君 * */ public abstract

随机推荐