首页 > 编程语言 >java aspose word 模板根据数据导出pdf

java aspose word 模板根据数据导出pdf

时间:2024-12-13 10:43:22浏览次数:12  
标签:jfree word java Color org chart new import pdf

支持以功能:

1、字符串占位符替换。

2、占位符循环替换。

3、图片替换。

4、基础图标,折现、饼图、柱状图。

 

 

本案例运行环境:

1、aspose word21.1版本。

2、jdk 18。

话不多说直接上代码。

<!-- 图表相关 -->
        <dependency>
            <groupId>jfree</groupId>
            <artifactId>jfreechart</artifactId>
            <version>1.0.13</version>
        </dependency>
        <!-- 文档处理 -->
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-words</artifactId>
            <version>21.1</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/aspose-words-21.1.jar</systemPath>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>
maven依赖
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.renderer.category.StandardBarPainter;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;

import java.awt.*;
import java.text.DecimalFormat;
import java.text.NumberFormat;

/**
 *@author pengbenlei
 *@date 2024/12/12 11:37
 *@desc
 */
public class ChartUtil {
    private static final Color[] BAR_COLORS = new Color[]{
            new Color(79, 129, 189),
            new Color(192, 80, 77),
            new Color(155, 187, 89),
    };

    private static final Color[] LINE_COLORS = new Color[]{
            new Color(237, 123, 46),
            new Color(90, 154, 213),
            new Color(164, 164, 164),
    };

    private static final Color[] PIE_COLORS = new Color[]{
            new Color(75, 172, 198),
            new Color(128, 100, 162),
            new Color(155, 187, 89),
            new Color(192, 80, 77),
            new Color(79, 129, 189),
            new Color(44, 77, 117),
            new Color(247, 150, 70),
            new Color(165, 165, 165),
    };


    private static StandardChartTheme initChartTheme() {
        StandardChartTheme currentTheme = new StandardChartTheme("JFree");
        // 横轴纵轴标题文字大小
        currentTheme.setLargeFont(new java.awt.Font("宋体", java.awt.Font.BOLD, 15));
        // 横轴纵轴数值文字大小
        currentTheme.setRegularFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 13));
        currentTheme.setExtraLargeFont(new java.awt.Font("宋体", java.awt.Font.BOLD, 20));
        // 背景颜色
        currentTheme.setPlotBackgroundPaint(new Color(255, 255, 204, 0));
        // 边框线条
        currentTheme.setPlotOutlinePaint(new Color(0, 0, 0, 0));
        // 网格线条
        currentTheme.setRangeGridlinePaint(new Color(78, 74, 74));
        return currentTheme;
    }

    /**
     * 线图
     *
     * @param title 标题
     * @param categoryAxisLabel 分类标签
     * @param valueAxisLabel 数值标签
     * @param dataset 数据集
     * @return org.jfree.chart.JFreeChart
     * @author Hou_fx
     * @date 2021.8.4 10:39
     */
    public static JFreeChart lineChart(String title, String categoryAxisLabel, String valueAxisLabel, DefaultCategoryDataset dataset) {
        ChartFactory.setChartTheme(initChartTheme());

        JFreeChart chart = ChartFactory.createLineChart(
                title,
                categoryAxisLabel,
                valueAxisLabel,
                dataset,
                PlotOrientation.VERTICAL,
                true,
                true,
                false
        );

        CategoryPlot plot = chart.getCategoryPlot();
        LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();
        // 折现点显示数值
        renderer.setBaseItemLabelsVisible(true);
        renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        // 更改线条颜色
        for (int i = 0; i < dataset.getRowKeys().size(); i++) {
            renderer.setSeriesPaint(i, LINE_COLORS[i]);
        }
        return chart;
    }

    /**
     * 柱状图
     *
     * @param title
     * @param categoryAxisLabel
     * @param valueAxisLabel
     * @param dataset           数据集
     * @return org.jfree.chart.JFreeChart
     * @author Hou_fx
     * @date 2021.8.4 14:03
     */
    public static JFreeChart barChart(String title, String categoryAxisLabel, String valueAxisLabel, DefaultCategoryDataset dataset) {
        ChartFactory.setChartTheme(initChartTheme());

        JFreeChart chart = ChartFactory.createBarChart(
                title,
                categoryAxisLabel,
                valueAxisLabel,
                dataset,
                PlotOrientation.VERTICAL,
                true,
                true,
                false
        );

        CategoryPlot plot = chart.getCategoryPlot();
        BarRenderer renderer = (BarRenderer) plot.getRenderer();
        // 纯色显示
        renderer.setBarPainter(new StandardBarPainter());
        // 柱子上显示小数字
        renderer.setBaseItemLabelsVisible(true);
        renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        // 设置柱子间隔
        renderer.setItemMargin(0.0);
        // 设置柱子颜色
        for (int i = 0; i < dataset.getRowKeys().size(); i++) {
            renderer.setSeriesPaint(i, BAR_COLORS[i]);
        }
        return chart;
    }

    /**
     * 饼图
     *
     * @param title
     * @param dataset
     * @return org.jfree.chart.JFreeChart
     * @author Hou_fx
     * @date 2021.8.4 14:04
     */
    public static JFreeChart pieChart(String title, DefaultPieDataset dataset) {
        ChartFactory.setChartTheme(initChartTheme());

        JFreeChart chart = ChartFactory.createPieChart(
                title,
                dataset,
                true,
                true,
                false
        );
        PiePlot plot = (PiePlot) chart.getPlot();
        // 设置扇区颜色
        for (int i = 0; i < dataset.getKeys().size(); i++) {
            plot.setSectionPaint(dataset.getKey(i), PIE_COLORS[i]);
        }
        // 设置扇区的线条颜色
        plot.setBaseSectionOutlinePaint(new Color(255, 255, 255));
        // 设置扇区的线条大小
        plot.setBaseSectionOutlineStroke(new BasicStroke(3));
        // 设置标签颜色
        plot.setLabelLinkPaint(new Color(255, 255, 255, 0));
        // 设置标签背景色
        plot.setLabelBackgroundPaint(new Color(255, 255, 255, 0));
        // 设置标签线条颜色
        plot.setLabelOutlinePaint(new Color(255, 255, 255, 0));
        // 设置标签阴影颜色
        plot.setLabelShadowPaint(new Color(255, 255, 255, 0));
        // 设置饼图阴影颜色
        plot.setShadowPaint(new Color(255, 255, 255, 0));
        // 添加标签数字百分比显示
        plot.setLabelGenerator(new StandardPieSectionLabelGenerator(("{0}{2}"), NumberFormat.getNumberInstance(), new DecimalFormat("0.00%")));
        return chart;
    }
}
图表相关工具类
import com.aspose.words.*;
import org.jfree.chart.ChartUtilities;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 *@author pengbenlei
 *@date 2024/12/12 15:07
 *@desc
 */
public class AsposeUtils {


    /**
     * 根据word模板生成pdf
     * @param template 模板路径
     * @param outPath  输出目录
     * @param dataJson  业务数据json字符串
     * @param sourceName 业务数据源名称
     * @param wordImages  图片集合
     * @throws Exception 异常信息
     */
    public static void getPdfByWordTemplate(String template, String outPath, String dataJson, String sourceName, List<WordImg> wordImages) throws Exception {
        // 验证
        Assert.isTrue(StringUtils.hasLength(template), "模板文件路径不能为空!");
        Assert.isTrue(StringUtils.hasLength(sourceName), "模板数据源名称!");
        Assert.isTrue(StringUtils.hasLength(outPath), "pdf输出路径不能为空!");
        // 将输入流转为doc
        Document doc = new Document(template);
        // doc构建
        DocumentBuilder builder = new DocumentBuilder(doc);
        // 填充数据
        JsonDataLoadOptions opt = new JsonDataLoadOptions();
        final ReportingEngine engine = new ReportingEngine();
        JsonDataSource jsonDataSource = new JsonDataSource(new ByteArrayInputStream(dataJson.getBytes()), opt);
        engine.buildReport(doc, jsonDataSource, sourceName);
        // 填充图片
        for (WordImg wordImage : wordImages) {
            if (!StringUtils.hasLength(wordImage.getBookmark())) {
                continue;
            }
            // 定位书签位置
            builder.moveToBookmark(wordImage.getBookmark());
            if (wordImage.getType() == 1 || wordImage.getType() == 3) {
                // 本地图片和网络url图片
                builder.insertImage(wordImage.getPath());
            } else if (wordImage.getType() == 2) {
                // 字节码图片
                builder.insertImage(wordImage.getImageBytes());
            }
        }
        // 转pdf
        doc.save(outPath, SaveFormat.PDF);
    }

    public static void main(String[] args) throws Exception {
        final String filePath = "C:\\Users\\Administrator\\Desktop\\上传整理\\新建文件夹\\temp.docx";
        final String outPath = "C:\\Users\\Administrator\\Desktop\\上传整理\\新建文件夹\\output.pdf";
        String jsonStr = "{\n" +
                "    \"age\": 20,\n" +
                "    \"birth\": \"1555-01-55\",\n" +
                "    \"checkNumber\": \"12349864\",\n" +
                "    \"idCard\": \"56456461645\",\n" +
                "    \"items\": [\n" +
                "        {\n" +
                "            \"checked\": false,\n" +
                "            \"itemName\": \"血常规\"\n" +
                "        },\n" +
                "        {\n" +
                "            \"checked\": false,\n" +
                "            \"itemName\": \"生化检验\"\n" +
                "        },\n" +
                "        {\n" +
                "            \"checked\": true,\n" +
                "            \"itemName\": \"尿常规\"\n" +
                "        }\n" +
                "    ],\n" +
                "    \"name\": \"张三三\",\n" +
                "    \"phone\": \"15445454454\",\n" +
                "    \"sex\": \"男\",\n" +
                "    \"title\": \"成都市温江区金马街道社区卫生服务中心\"\n" +
                "}";
        DefaultCategoryDataset lineDataset = new DefaultCategoryDataset();
        for (int i = 1; i < 10; i++) {
            lineDataset.addValue(i, "张儿", String.valueOf((i * 2)));
        }

        for (int i = 1; i < 5; i++) {
            lineDataset.addValue(i, "李儿", String.valueOf((i * 3)));
        }
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        // 折线图
//        ChartUtilities.writeChartAsJPEG(bos, ChartUtil.lineChart("测试折线图", "A", "B", lineDataset),
//                300, 300);
        // 折线图
//        ChartUtilities.writeChartAsJPEG(bos, ChartUtil.lineChart("测试折线图", "A", "B", lineDataset),
//                (int) signRect.getWidth(), (int) signRect.getHeight());
        // 饼图
        DefaultPieDataset defaultPieDataset = new DefaultPieDataset();
        defaultPieDataset.setValue("Category A", 40); // 类别 A 占 40%
        defaultPieDataset.setValue("Category B", 30); // 类别 B 占 30%
        defaultPieDataset.setValue("Category C", 20); // 类别 C 占 20%
        defaultPieDataset.setValue("Category D", 10); // 类别 D 占 10%
        ChartUtilities.writeChartAsJPEG(bos, ChartUtil.pieChart("测试饼图", defaultPieDataset),
                200, 200);
//        ChartUtilities.writeChartAsJPEG(bos, ChartUtil.barChart("测试柱状图", "A", "B", lineDataset),
//                200, 200);
        byte[] imageBytes = bos.toByteArray();
        List<WordImg> wordImages = new ArrayList<>();
        // 二维码
        WordImg wordImg1 = WordImg.builder()
                .bookmark("qrCode")
                .type(1)
                .path("C:\\Users\\Administrator\\Desktop\\上传整理\\新建文件夹\\0.jpg")
                .build();
        wordImages.add(wordImg1);
        WordImg wordImg2 = WordImg.builder()
                .bookmark("lineImg")
                .type(2)
                .imageBytes(imageBytes)
                .build();
        wordImages.add(wordImg2);
        getPdfByWordTemplate(filePath, outPath, jsonStr, "data", wordImages);
    }
}
文件处理工具类
import lombok.Builder;
import lombok.Data;

/**
 *@author pengbenlei
 *@date 2024/12/13 9:37
 *@desc Aspose图片数据
 */
@Data
@Builder
public class WordImg {

    /**
     * 占位书签名
     */
    private String bookmark;

    /**
     * 图片处理类型 1-本地图片 2-imageBytes  3-网络url图片
     */
    private int type;

    /**
     * 图片路径
     */
    private String path;

    /**
     * 图片字节数组
     */
    private byte[] imageBytes;
}
图片

以上就能实现大部分模板替换的业务功能,下面说下模板的设计。

1、一般使用table对word模板布局。

2、占位符和模板语法查阅官方文档,或者看我的截图。

3、图片使用书签占位。

 

 

标签:jfree,word,java,Color,org,chart,new,import,pdf
From: https://www.cnblogs.com/rolayblog/p/18604401

相关文章

  • JAVA中 普通方法/变量,静态方法/变量,之间的相互调用
    publicclassMyapp{//普通变量inta=1;//静态变量staticStringstr="字符串";//普通方法publicvoidMethod1(){//普通方法中可以使用普通属性/方法,静态属性/静态方法均是直接调用即可System.out.println(a);S......
  • 初始JavaEE篇 —— 网络原理---应用层协议
     找往期文章包括但不限于本期文章中不懂的知识点:个人主页:我要学编程程(ಥ_ಥ)-CSDN博客所属专栏:JavaEE我们在前面简单的接触了 TCP/IP五层协议中的传输层协议,并使用UDP协议与TCP协议编写了一个简单的回显服务器与客户端。接下来,我们来深入学习应用层的协议。应用......
  • 谈谈服务雪崩效应?思维导图 代码示例(java 架构)
    服务雪崩效应是指在分布式系统或微服务架构中,当一个服务出现故障时,可能会导致调用它的其他服务也出现问题,进而引发连锁反应,最终造成整个系统的大面积瘫痪。这种情况就像雪崩一样,一旦开始就难以控制。服务雪崩的原因单点故障:某个关键组件的失败可能导致依赖它的所有服务都......
  • origin导出jpg/png图片后如何解决图片插入word中空白过多的问题
            关于origin如何导出宽高/大小格式统一的jpg/png图请看我上一篇文章        origin导出宽高/大小格式统一的jpg图片_怎么保证origin输出图片大小一致-CSDN博客        在导出jpg图片前,如果不进行任何操作,导出的图片插入到word里面会出现空白......
  • 深入理解 JavaScript 柯里化: 提升函数的复用性和灵活性
    引言在JS编程中,函数是一等公民,具备了强大的灵活性和复用性。而柯里化作为一种高阶技术,可以进一步提升函数的复用性和灵活性。通过柯里化,可以大大简化函数的调用方式,并创建更加灵活和可复用的函数在本篇博客中,我们将深入探讨JS中柯里化的概念和原理,并......
  • [Java]File文件对象
    File类是java.io包下的类,File类的对象,用于操作当前系统的文件或文件夹File类只能操作文件本身,不能读写文件里的数据创建File对象补充路径分隔符正斜杠/反斜杠\\跨平台File.separatoeFile对象可以指向不存在的文件路径:Filef3=newFile("不存在的文件路径......
  • 132Java基于SpringBoot的西山区家政服务网站设计与开发-java vue.js idea
    所需该项目可以在最下面查看联系方式,为防止迷路可以收藏文章,以防后期找不到项目介绍132Java基于SpringBoot的西山区家政服务网站设计与开发-javavue.jsidea系统实现截图技术栈介绍JDK版本:jdk1.8+编程语言:java框架支持:springboot数据库:mysql......
  • 150Java基于SpringBoot的高校实验室管理系统微信小程序-java vue.js idea
    所需该项目可以在最下面查看联系方式,为防止迷路可以收藏文章,以防后期找不到项目介绍150Java基于SpringBoot的高校实验室管理系统设计与实现-javavue.jsidea系统实现截图技术栈介绍JDK版本:jdk1.8+编程语言:java框架支持:springboot数据库:mysql版本不限......
  • Java 中枚举的 toString`方法及其字段信息展示
    在Java编程中,枚举(enum)是一种特殊的数据类型,用于定义一组固定的常量。枚举类型不仅限于简单的常量定义,还可以包含字段、方法以及构造函数,从而使其具备更强的表达能力。toString方法是Java中所有对象都继承自Object类的一个方法,用于返回对象的字符串表示。对于枚举类型,默认情......
  • java雪花算法
    雪花算法适用于高并发、分布式系统中生成唯一标识符。通过合理的位数设计,确保了ID的唯一性和有序性,非常适合需要快速生成唯一ID的场景。雪花算法是一种分布式唯一ID生成算法,由Twitter开发。它生成的ID是64位的整数,具有时间排序的特性。其结构如下:```|1bit|41bits......