02——Java使用低版本poi 3.8 + itext 2.1.7 + itextasian.1.5.2 实现word转PDF——02(解决段落样式问题 + 图片问题 + 单个表格问题)

1. 前言

1.1 关于docx转PDF解决汉字展示问题

2. docx转PDF(第4版——解决图片问题)

2.1 依赖保持不变

  • 如下(关于 itextasian 1.5.2 依赖的下载看上篇文章):
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.8</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-scratchpad</artifactId>
        <version>3.8</version>
    </dependency>
    
    <!--        <dependency>-->
    <!--            <groupId>fr.opensagres.xdocreport</groupId>-->
    <!--            <artifactId>org.apache.poi.xwpf.converter.pdf</artifactId>-->
    <!--            <version>1.0.6</version>-->
    <!--        </dependency>-->
    
    <dependency>
        <groupId>com.lowagie</groupId>
        <artifactId>itext</artifactId>
        <version>2.1.7</version>
    </dependency>
    
    
    <!--解决word转PDF后中文不显示问题-->
    <dependency>
        <groupId>com.lowagie</groupId>
        <artifactId>itextasian</artifactId>
        <version>1.5.2</version>
    </dependency>
    

2.2 核心代码

  • 如下:
    在这里插入图片描述

2.3 观看效果

  • 如下:
    在这里插入图片描述

2.4 完整实现代码

  • 如下:
    package com.liu.susu.word2pdf.example4;
    
    import com.liu.susu.word2pdf.example3.RgbUtils;
    import com.lowagie.text.Document;
    import com.lowagie.text.Font;
    import com.lowagie.text.*;
    import com.lowagie.text.Image;
    import com.lowagie.text.pdf.BaseFont;
    import com.lowagie.text.pdf.PdfWriter;
    import org.apache.poi.xwpf.usermodel.*;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.util.List;
    
    /**
     * @Description 第4版:解决 word转PDF 的图片问题
     * @Author susu
     * @Date 2024/3/28
     */
    public class Word2Pdf_Test4 {
        public static void main(String[] args) throws DocumentException, IOException {
            String wordFilePath = "/Users/susu/file_test/about_word/test_word_to_pdf_1/test_word_in_3.docx";
            String pdfFilePath = "/Users/susu/file_test/about_word/test_word_to_pdf_1/test_word_out_0328_3.pdf";
    
            word2pdf(wordFilePath, pdfFilePath);
    
        }
    
        public static void word2pdf(String wordPath, String pdfPath) throws IOException, DocumentException {
            XWPFDocument xwpfDocument = new XWPFDocument(new FileInputStream(wordPath));
    
            Document pdfDocument = new Document();
            PdfWriter.getInstance(pdfDocument, new FileOutputStream(pdfPath));
            pdfDocument.open();
    
            for (XWPFParagraph paragraph : xwpfDocument.getParagraphs()) {
                List<XWPFRun> runs = paragraph.getRuns();
                Paragraph paragraph2 = new Paragraph();
    
                for (int i = 0; i < runs.size(); i++) {
                    XWPFRun run = runs.get(i);
                    String text = run.getText(run.getTextPosition());
    
                    // 1. 解决图片问题
                    List<XWPFPicture> pictures = run.getEmbeddedPictures();
                    for (XWPFPicture picture : pictures) {
    
                        XWPFPictureData pictureData = picture.getPictureData();
                        byte[] imageBytes = pictureData.getData();
    
                        // 使用 ImageIO 读取图片,获取图片宽高
                        InputStream inputStream = new ByteArrayInputStream(imageBytes);
                        BufferedImage bufferedImage = ImageIO.read(inputStream);
                        int width = bufferedImage.getWidth();
                        int height = bufferedImage.getHeight();
                        System.out.println(width + "--->" +height);
    
    //                    Image image = Image.getInstance(bufferedImage,null);
                        Image image = Image.getInstance(imageBytes);
                        image.scaleAbsolute(width/3,height/3); // 调整图片宽高(如果不调整,图片的宽高是原始图片的大小而不是word图片里调整后的大小)
    
                        paragraph2.add(image);
                    }
    
                    // 2. 字体样式等问题解决
                    // 2.1. 字体大小
                    int fontSize = run.getFontSize();
    
                    // 2.2. 字体颜色
                    int[] rgbNum = RgbUtils.getRgbNum(run.getColor());
                    Color color = new Color(rgbNum[0], rgbNum[1], rgbNum[2]);
    
                    // 2.3. 字体样式
                    String fontStyle = "";
                    if (run.isBold()) {
                        fontStyle += "bold";
                    } else if (run.isItalic()) {
                        fontStyle += "italic";
                    } else if (run.getUnderline().getValue() == 1) {
                        fontStyle += "underline";
                    }
    
                    BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                    Font font = new Font(baseFont, fontSize, Font.NORMAL, color);
                    font.setStyle(fontStyle); // 字体样式
    
                    if (text != null) {
                        Chunk chObj1 = new Chunk(text, font);
                        paragraph2.add(chObj1);
                    }
                }
                pdfDocument.add(paragraph2);
            }
            pdfDocument.close();
        }
    
    }
    
    

2.5 存在的问题

  • 由上面效果可看到,word转PDF的代码实现的效果依然不是很完善,1是表格问题,2是段落样式问题!请继续……

3. docx转PDF(第5版——解决表格问题)

3.1 实现代码

  • 如下:
    在这里插入图片描述
    package com.liu.susu.word2pdf.example5;
    
    import com.liu.susu.word2pdf.example3.RgbUtils;
    import com.lowagie.text.Document;
    import com.lowagie.text.Font;
    import com.lowagie.text.Image;
    import com.lowagie.text.*;
    import com.lowagie.text.pdf.BaseFont;
    import com.lowagie.text.pdf.PdfPCell;
    import com.lowagie.text.pdf.PdfPTable;
    import com.lowagie.text.pdf.PdfWriter;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.poi.xwpf.usermodel.*;
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.util.List;
    
    /**
     * @Description 第5版:解决 word转PDF 的表格问题
     * @Author susu
     * @Date 2024/3/28
     */
    public class Word2Pdf_Test5 {
        public static void main(String[] args) throws DocumentException, IOException {
            String wordFilePath = "/Users/susu/file_test/about_word/test_word_to_pdf_1/test_word_in_3.docx";
            String pdfFilePath = "/Users/susu/file_test/about_word/test_word_to_pdf_1/test_word_out_0328_5.pdf";
    
            word2pdf(wordFilePath, pdfFilePath);
    
        }
    
        public static void word2pdf(String wordPath, String pdfPath) throws IOException, DocumentException {
            XWPFDocument xwpfDocument = new XWPFDocument(new FileInputStream(wordPath));
    
            Document pdfDocument = new Document();
            PdfWriter.getInstance(pdfDocument, new FileOutputStream(pdfPath));
            pdfDocument.open();
    
            List<XWPFTable> tables = xwpfDocument.getTables(); // word里的所有表格
            for (XWPFParagraph paragraph : xwpfDocument.getParagraphs()) {
    //            System.out.println(paragraph.getText());
                List<XWPFRun> runs = paragraph.getRuns();
    
                Paragraph paragraph2 = new Paragraph();
    
                if (runs != null && runs.size() > 0) {
                    for (int i = 0; i < runs.size(); i++) {
                        XWPFRun run = runs.get(i);
                        String text = run.getText(run.getTextPosition());
                        List<XWPFPicture> pictures = run.getEmbeddedPictures();
    
                        if (StringUtils.isNoneBlank(text)) {
                            // 1. 处理字体——字体样式等问题解决
                            // 1.1. 字体大小
                            int fontSize = run.getFontSize();
    
                            // 1.2. 字体颜色
                            int[] rgbNum = RgbUtils.getRgbNum(run.getColor());
                            Color color = new Color(rgbNum[0], rgbNum[1], rgbNum[2]);
    
                            // 1.3. 字体样式
                            String fontStyle = "";
                            if (run.isBold()) {
                                fontStyle += "bold";
                            } else if (run.isItalic()) {
                                fontStyle += "italic";
                            } else if (run.getUnderline().getValue() == 1) {
                                fontStyle += "underline";
                            }
    
                            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                            Font font = new Font(baseFont, fontSize, Font.NORMAL, color);
                            font.setStyle(fontStyle); // 字体样式
    
                            Chunk chObj1 = new Chunk(text, font);
                            paragraph2.add(chObj1);
    
                        } else if (pictures != null && pictures.size() > 0) {
                            // 1. 解决图片问题
                            for (XWPFPicture picture : pictures) {
    
                                XWPFPictureData pictureData = picture.getPictureData();
                                byte[] imageBytes = pictureData.getData();
    
                                // 使用 ImageIO 读取图片,获取图片宽高
                                InputStream inputStream = new ByteArrayInputStream(imageBytes);
                                BufferedImage bufferedImage = ImageIO.read(inputStream);
                                int width = bufferedImage.getWidth();
                                int height = bufferedImage.getHeight();
                                System.out.println(width + "--->" + height);
    
    //                    Image image = Image.getInstance(bufferedImage,null);
                                Image image = Image.getInstance(imageBytes);
                                image.scaleAbsolute(width / 3, height / 3); // 调整图片宽高(如果不调整,图片的宽高是原始图片的大小而不是word图片里调整后的大小)
    
                                paragraph2.add(image);
                            }
                        }
    
                    }
    
                }else {
                    // 3. 解决表格问题
                    /**
                     * 存在的问题
                     * (1)word文档里不能有空段落,否则空段落也进来
                     * (2)文档里有多个表格的话不适用,不能定位表格在哪个段落里
                     */
                    for (XWPFTable table : tables) {
                        PdfPTable pdfTable = new PdfPTable(table.getNumberOfRows());
                        // 遍历表格中的每一行
                        for (XWPFTableRow row : table.getRows()) {
                            // 遍历行中的每个单元格
                            for (XWPFTableCell cell : row.getTableCells()) {
                                // 获取单元格中的文本内容
                            String cellText = cell.getText();
                                BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                                Font font = new Font(baseFont, 10, Font.NORMAL, Color.BLACK);
    
                                Chunk chObj1 = new Chunk(cellText, font);
    //                            pdfTable.addCell(new PdfPCell(new Phrase(cell.getText())));
                                pdfTable.addCell(new PdfPCell(new Phrase(chObj1)));
                            }
                        }
                        paragraph2.add(pdfTable);
                    }
                }
    
                pdfDocument.add(paragraph2);
            }
            pdfDocument.close();
        }
    
    }
    
    

3.2 效果

  • 如下:
    在这里插入图片描述

3.3 存在的问题

  • 代码逻辑很简单,如果word里有空行,不支持(影响表格的判断);
  • 文档里有多个表格的话,目前代码不支持使用,因为没有定位表格的具体位置(具体段落定位不了)。
  • 关于段落样式问题,请继续……

4. docx转PDF(第6版——解决段落样式问题)

4.1 解决的问题

  • 本版主要解决:word转PDF 中的段落样式问题(对齐、段落间距、行间距、首行缩进、段落中字体背景颜色)。

4.2 观看效果

  • 如下:
    在这里插入图片描述

4.3 核心代码

  • 如下:
    在这里插入图片描述
    在这里插入图片描述

4.4 遇到的问题

  • 问题描述:CTHighlight类不存在,如下:
    找不到org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHighlight的类
    
  • 分析问题:
    poi提供的那个ooxml-schemas-x.x.jar(这里指的是ooxml-schemas-3.8.jar)包是精简版的,为了节省空间,里面放的只有一些常用的模块,所以要引用另外一些功能的话就需要引用完全版的ooxml-schemas.jar(这里对应的是ooxml-schemas-1.1.jar)包
  • 解决问题,引入 ooxml-schemas-1.1.jar 依赖即可,如下:
    在这里插入图片描述
    <!-- https://mvnrepository.com/artifact/org.apache.poi/ooxml-schemas -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>ooxml-schemas</artifactId>
        <version>1.1</version>
    </dependency>
    

4.5 完整代码

  • 如下:
    package com.liu.susu.word2pdf.example6;
    
    import com.liu.susu.word2pdf.example3.RgbUtils;
    import com.lowagie.text.Document;
    import com.lowagie.text.Font;
    import com.lowagie.text.Image;
    import com.lowagie.text.*;
    import com.lowagie.text.pdf.BaseFont;
    import com.lowagie.text.pdf.PdfPCell;
    import com.lowagie.text.pdf.PdfPTable;
    import com.lowagie.text.pdf.PdfWriter;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.poi.xwpf.usermodel.*;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
    
    import javax.imageio.ImageIO;
    import javax.swing.text.html.StyleSheet;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.util.List;
    
    import static javax.swing.text.StyleConstants.LineSpacing;
    
    /**
     * @Description 第6版:解决 word转PDF 中的段落样式问题(对齐、段落间距、行间距、首行缩进、段落中字体背景颜色)
     * @Author susu
     * @Date 2024/3/28
     */
    public class Word2Pdf_Test6 {
        public static void main(String[] args) throws DocumentException, IOException {
            String wordFilePath = "/Users/susu/file_test/about_word/test_word_to_pdf_1/test_word_in_3.docx";
            String pdfFilePath = "/Users/susu/file_test/about_word/test_word_to_pdf_1/test_word_out_0328_6.pdf";
    
            word2pdf(wordFilePath, pdfFilePath);
    
        }
    
        public static void word2pdf(String wordPath, String pdfPath) throws IOException, DocumentException {
            XWPFDocument xwpfDocument = new XWPFDocument(new FileInputStream(wordPath));
    
            Document pdfDocument = new Document();
            PdfWriter.getInstance(pdfDocument, new FileOutputStream(pdfPath));
            pdfDocument.open();
    
            List<XWPFTable> tables = xwpfDocument.getTables(); // word里的所有表格
            for (XWPFParagraph paragraph : xwpfDocument.getParagraphs()) {
                List<XWPFRun> runs = paragraph.getRuns();
                Paragraph paragraph2 = new Paragraph();
    
                // 1. 解决段落样式问题(对齐、段落间距、行间距、首行缩进)
                // 1.1 对齐
                ParagraphAlignment alignment = paragraph.getAlignment();
                paragraph2.setAlignment(alignment.name());
    
                // 1.2 段落之间的间距
                paragraph2.setSpacingAfter(paragraph.getSpacingAfter() * 0.05f);
    
                // 1.3 段落中的行间距
                CTSpacing ctSpacing = paragraph.getCTP().getPPr().getSpacing();
                if (ctSpacing.getLine() != null){
                    paragraph2.setLeading(ctSpacing.getLine().intValue() * 0.06f);
                }
    
                // 1.4 首行缩进
                paragraph2.setFirstLineIndent(paragraph.getIndentationFirstLine() * 0.05f);
    
                if (runs != null && runs.size() > 0) {
                    for (int i = 0; i < runs.size(); i++) {
                        XWPFRun run = runs.get(i);
                        String text = run.getText(run.getTextPosition());
                        List<XWPFPicture> pictures = run.getEmbeddedPictures();
    
                        if (StringUtils.isNoneBlank(text)) {
                            // 2. 处理字体——字体样式等问题解决
                            // 2.1. 字体大小
                            int fontSize = run.getFontSize();
    
                            // 2.2. 字体颜色
                            int[] rgbNum = RgbUtils.getRgbNum(run.getColor());
                            Color color = new Color(rgbNum[0], rgbNum[1], rgbNum[2]);
    
                            // 2.3. 字体样式
                            String fontStyle = "";
                            if (run.isBold()) {
                                fontStyle += "bold";
                            } else if (run.isItalic()) {
                                fontStyle += "italic";
                            } else if (run.getUnderline().getValue() == 1) {
                                fontStyle += "underline";
                            }
    
                            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                            Font font = new Font(baseFont, fontSize, Font.NORMAL, color);
                            font.setStyle(fontStyle); // 字体样式
    
                            // 2.4 获取word文档里的字体背景颜色
                            StyleSheet style = new StyleSheet();
                            CTRPr rPr = run.getCTR().getRPr();
                            CTHighlight highlight = rPr.getHighlight();
                            String backgroundColorName = highlight.getVal().toString();
                            Color backgroundColor = style.stringToColor(backgroundColorName);
    
                            Chunk chObj1 = new Chunk(text, font);
                            if (backgroundColor != null) {
                                // 设置字体背景颜色
                                chObj1.setBackground(backgroundColor);
                            }
                            paragraph2.add(chObj1);
    
                        } else if (pictures != null && pictures.size() > 0) {
                            // 3. 解决图片问题
                            for (XWPFPicture picture : pictures) {
    
                                XWPFPictureData pictureData = picture.getPictureData();
                                byte[] imageBytes = pictureData.getData();
    
                                // 使用 ImageIO 读取图片,获取图片宽高
                                InputStream inputStream = new ByteArrayInputStream(imageBytes);
                                BufferedImage bufferedImage = ImageIO.read(inputStream);
                                int width = bufferedImage.getWidth();
                                int height = bufferedImage.getHeight();
                                System.out.println(width + "--->" + height);
    
    //                    Image image = Image.getInstance(bufferedImage,null);
                                Image image = Image.getInstance(imageBytes);
                                image.scaleAbsolute(width / 3, height / 3); // 调整图片宽高(如果不调整,图片的宽高是原始图片的大小而不是word图片里调整后的大小)
    
                                paragraph2.add(image);
                            }
                        }
    
                    }
    
                }else {
                    // 4. 解决表格问题
                    /**
                     * 存在的问题
                     * (1)word文档里不能有空段落,否则空段落也进来
                     * (2)文档里有多个表格的话不适用,不能定位表格在哪个段落里
                     */
                    for (XWPFTable table : tables) {
                        PdfPTable pdfTable = new PdfPTable(table.getNumberOfRows());
                        // 遍历表格中的每一行
                        for (XWPFTableRow row : table.getRows()) {
                            // 遍历行中的每个单元格
                            for (XWPFTableCell cell : row.getTableCells()) {
                                // 获取单元格中的文本内容
                            String cellText = cell.getText();
                                BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                                Font font = new Font(baseFont, 10, Font.NORMAL, Color.BLACK);
    
                                Chunk chObj1 = new Chunk(cellText, font);
    //                            pdfTable.addCell(new PdfPCell(new Phrase(cell.getText())));
                                pdfTable.addCell(new PdfPCell(new Phrase(chObj1)));
                            }
                        }
                        paragraph2.add(pdfTable);
                    }
                }
    
                pdfDocument.add(paragraph2);
            }
            pdfDocument.close();
        }
    
    }
    
    

4.6 遗留的问题

  • 就是上面的表格相关问题(多表格等问题)

5. 终版——关于表格问题的解决

  • 14
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@素素~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值