美文网首页
Docx4j实现Word转Pdf

Docx4j实现Word转Pdf

作者: 滴雨幻想 | 来源:发表于2018-08-06 11:20 被阅读0次

    此例通过docx4j实现word转成pdf。
    因功能较简单,只在此展示一下后台功能代码。
    1.公用方法类

    package com.ldht.common.util.wordPdf;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.poi.POIXMLDocument;
    import org.apache.poi.util.IOUtils;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    import org.docx4j.convert.out.pdf.PdfConversion;
    import org.docx4j.convert.out.pdf.viaXSLFO.PdfSettings;
    import org.docx4j.fonts.IdentityPlusMapper;
    import org.docx4j.fonts.Mapper;
    import org.docx4j.fonts.PhysicalFonts;
    import org.docx4j.jaxb.Context;
    import org.docx4j.openpackaging.exceptions.Docx4JException;
    import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
    import org.docx4j.openpackaging.parts.PartName;
    import org.docx4j.openpackaging.parts.WordprocessingML.AlternativeFormatInputPart;
    import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
    import org.docx4j.relationships.Relationship;
    import org.docx4j.wml.CTAltChunk;
    
    /**
     * @author HMZ
     */
    public class WordUtil {
        public void mergeDocx(HttpServletResponse response,List<String> list){  
            List<InputStream>  inList=new ArrayList<InputStream>();  
              for(int i=0;i<list.size();i++)  
                try {  
                    inList.add(new FileInputStream(list.get(i)));  
                } catch (FileNotFoundException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
              try {  
                InputStream inputStream=mergeDocx(inList);  
                saveTemplate(response,inputStream);  
            } catch ( IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            } catch (Docx4JException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }  
        }  
          
        public InputStream mergeDocx(final List<InputStream> streams)  throws Docx4JException, IOException {    
        
            WordprocessingMLPackage target = null;    
            final File generated = File.createTempFile("generated", ".docx");    
        
            int chunkId = 0;    
            Iterator<InputStream> it = streams.iterator();    
            while (it.hasNext()) {    
                InputStream is = it.next();    
                if (is != null) {    
                    if (target == null) {    
                        // Copy first (master) document    
                        OutputStream os = new FileOutputStream(generated);    
                        os.write(IOUtils.toByteArray(is));    
                        os.close();    
            
                        target = WordprocessingMLPackage.load(generated);    
                    } else {    
                        // Attach the others (Alternative input parts)    
                        insertDocx(target.getMainDocumentPart(),    
                                IOUtils.toByteArray(is), chunkId++);    
                    }    
                }    
            }    
            
            if (target != null) {    
                target.save(generated);    
                FileInputStream input = new FileInputStream(generated);
                //获取docx解析对象
    //            XWPFDocument document = new XWPFDocument(target);
                return new FileInputStream(generated);    
            } else {    
                return null;    
            }    
        }    
        
        // 插入文档    
        private void insertDocx(MainDocumentPart main, byte[] bytes, int chunkId) {    
            try {    
                AlternativeFormatInputPart afiPart = new AlternativeFormatInputPart(    
                        new PartName("/part" + chunkId + ".docx"));    
             //   afiPart.setContentType(new ContentType(CONTENT_TYPE));    
                afiPart.setBinaryData(bytes);    
                Relationship altChunkRel = main.addTargetPart(afiPart);    
            
                CTAltChunk chunk = Context.getWmlObjectFactory().createCTAltChunk();    
                chunk.setId(altChunkRel.getId());    
            
                main.addObject(chunk);    
            } catch (Exception e) {    
                e.printStackTrace();    
            }    
        }                                    
      
        public  void saveTemplate(HttpServletResponse response,InputStream fis) throws IOException{  
            OutputStream fos = response.getOutputStream();  
            int bytesum = 0;     
            int byteread = 0;  
            try {  
                byte[] buffer = new byte[10240];   
                while ( (byteread = fis.read(buffer)) != -1) {     
                    bytesum += byteread; //字节数 文件大小    
                    fos.write(buffer, 0, byteread);     
                }     
                fis.close();   
                fos.close();  
            } catch (FileNotFoundException e1) {  
                e1.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
        
        /** 
         * docx文档转换为PDF 
         * @param docx docx文档 
         * @param pdfPath PDF文档存储路径 
         * @throws Exception 可能为Docx4JException, FileNotFoundException, IOException等 
         */  
        @SuppressWarnings("deprecation")
        public void convertDocxToPDF(File docx, String pdfPath) throws Exception {  
            OutputStream os = null;  
            try {  
                WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(docx);  
    //            Mapper fontMapper = new BestMatchingMapper();   
                Mapper fontMapper = new IdentityPlusMapper();  
                //中文字体转换
                fontMapper.getFontMappings().put("华文行楷", PhysicalFonts.getPhysicalFonts().get("STXingkai"));  
                fontMapper.getFontMappings().put("隶书", PhysicalFonts.getPhysicalFonts().get("LiSu"));
                fontMapper.getFontMappings().put("宋体",PhysicalFonts.getPhysicalFonts().get("SimSun"));
                fontMapper.getFontMappings().put("微软雅黑",PhysicalFonts.getPhysicalFonts().get("Microsoft Yahei"));
                fontMapper.getFontMappings().put("黑体",PhysicalFonts.getPhysicalFonts().get("SimHei"));
                fontMapper.getFontMappings().put("楷体",PhysicalFonts.getPhysicalFonts().get("KaiTi"));
                fontMapper.getFontMappings().put("新宋体",PhysicalFonts.getPhysicalFonts().get("NSimSun"));
                fontMapper.getFontMappings().put("华文行楷", PhysicalFonts.getPhysicalFonts().get("STXingkai"));
                fontMapper.getFontMappings().put("华文仿宋", PhysicalFonts.getPhysicalFonts().get("STFangsong"));
                fontMapper.getFontMappings().put("宋体扩展",PhysicalFonts.getPhysicalFonts().get("simsun-extB"));
                fontMapper.getFontMappings().put("仿宋",PhysicalFonts.getPhysicalFonts().get("FangSong"));
                fontMapper.getFontMappings().put("仿宋_GB2312",PhysicalFonts.getPhysicalFonts().get("FangSong_GB2312"));
                fontMapper.getFontMappings().put("幼圆",PhysicalFonts.getPhysicalFonts().get("YouYuan"));
                fontMapper.getFontMappings().put("华文宋体",PhysicalFonts.getPhysicalFonts().get("STSong"));
                fontMapper.getFontMappings().put("华文中宋",PhysicalFonts.getPhysicalFonts().get("STZhongsong"));
                mlPackage.setFontMapper(fontMapper);  
          
                PdfConversion conversion = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion(mlPackage);  
                os = new FileOutputStream(pdfPath);  
                 
                conversion.output(os, new PdfSettings());  
            } finally {  
                IOUtils.closeQuietly(os);  
            }  
        }  
        
        /**
         * 将文件内容写入到临时文件中
         * @param inputUrl
         * @param file
         * @throws IOException
         */
        public void createFile(String inputUrl,File file) throws IOException{
             //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();
        }
        
        /**
         * 替换文本
         * @param document docx解析对象
         */
        public static void changeText(XWPFDocument document, String oldValue, String newValue){
            //获取段落集合
            List<XWPFParagraph> paragraphs = document.getParagraphs();
    
            for (XWPFParagraph paragraph : paragraphs) {
                //判断此段落时候需要进行替换
                String text = paragraph.getText();
                if(text.indexOf("^m^p")!= -1 || text.indexOf("^p^m")!= -1){
                    List<XWPFRun> runs = paragraph.getRuns();
                    for (XWPFRun run : runs) {
                        //替换模板原来位置
                        run.setText("^m",0);
                    }
                }
            }
        }
        
    }
    
    

    2.如何调用

    WordUtil.convertDocxToPDF(wordFile,pdfFilePath);
    

    3.说明
    convertDocxToPDF方法中定义的fontMapper,用于存放各类字体的转换关系,若不声明,则转换后有可能出现乱码。word中尽量使用宋体等常用字体,包括在Linux系统中,也需要安装相应的字体,才能解决乱码问题。

    相关文章

      网友评论

          本文标题:Docx4j实现Word转Pdf

          本文链接:https://www.haomeiwen.com/subject/nbuwvftx.html