跳至主要內容

SpringBoot数据处理

wangdx大约 17 分钟

对象转换处理

对象接收与 Rest 返回

  • 在进行用户请求时,除了可以单个接收请求参数之外,也可以直接利用 SpringMVC 提供的转换机制将请求参数的内容设置到指定类型的对象实例之中,同时在 Action 处理方法内部也可以利用“@ResponseBody”注解将指定的对象实例以 Rest 风格的形式进行数据输出

Action 类程序开发结构

  • 在进行请求参数接收时一般都会传递日期或日期时间型的数据,则按照 SpringMVC 的设计要求,此时应该在项目中设计有一个 WebDataBinder 器进行转换处理
1、
package com.yootk.vo;

import lombok.Data;

import java.util.Date;
@Data // 只要使用Lombok组件,99%的情况下就使用这一个注解
public class Message {
    private String title; // 字符串的参数
    private Date pubdate; // 日期参数
    private String content;
}


2、
project('microboot-web') { // 子模块
    dependencies { // 配置子模块依赖
        compile(project(':microboot-common')) // 引入其他子模块
    }
}
project('microboot-common') { // 子模块
    dependencies { // 配置子模块依赖
        compile('org.springframework.boot:spring-boot-starter-web') // 引入SpringBoot依赖
    }
}

3、
package com.yootk.common.action.abs;

import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

import java.beans.PropertyEditorSupport;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public abstract class AbstractBaseAction { // 定义一个公共的Action类
    // 在现在的开发之中如果要将字符串转为日期时间,考虑到多线程环境下的并发问题,所以一定要使用LocalDate
    private static final DateTimeFormatter LOCAL_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(java.util.Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                LocalDate localDate = LocalDate.parse(text, LOCAL_DATE_FORMAT);
                Instant instant = localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
                super.setValue(java.util.Date.from(instant));
            }
        });
    }
}


4、
package com.yootk.action;

import com.yootk.common.action.abs.AbstractBaseAction;
import com.yootk.vo.Message;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController // 直接基于Rest架构进行处理,省略了@ResponseBody注解
@RequestMapping("/message/*") // 添加父路径
public class MessageAction extends AbstractBaseAction { // 控制层的实现类
    @RequestMapping("echo") // 子路径
    public Object echo(Message message) { // 进行请求参数的接收以及请求内容的回应
        message.setTitle("【ECHO】" + message.getTitle());
        message.setContent("【ECHO】" + message.getContent());
        return message;
    }
}


5、
jar {enabled = true} // 允许当前的模块打包为“*.jar”文件
javadocTask {enabled = false} // 不启用javadoc任务
javadocJar {enabled = false} // 不生成javadoc的“*.jar”文件
bootJar {enabled = false} // 不执行SpringBoot的打包命令

6、
gradle build

7、
localhost:8080/message/echo?title=沐言科技&content=www.yootk.com&pubdate=1998-09-19

整合 FastJSON 组件

整合 FastJSON 组件

  • 在 SpringMVC 开发框架中都是默认通过 Jackson 工具类实现输出对象与 JSON 数据之间的转换处理操作,但是现在在国内使用较多的阿里推出的 FastJSON 组件,如果开发者需要将默认的 Jackson 转换组件更换为 FastJSON 转换组件

fastjson2 集成 springmvcopen in new window

1、
// https://mvnrepository.com/artifact/com.alibaba/fastjson
implementation group: 'com.alibaba', name: 'fastjson', version: '1.2.75'
// https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2
implementation group: 'com.alibaba.fastjson2', name: 'fastjson2', version: '2.0.47'
// https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2-extension
implementation group: 'com.alibaba.fastjson2', name: 'fastjson2-extension', version: '2.0.47'
#参考官网 https://alibaba.github.io/fastjson2/
// https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2-extension-spring6
implementation group: 'com.alibaba.fastjson2', name: 'fastjson2-extension-spring6', version: '2.0.47'




2、
ext.versions = [    // 定义所有要使用的版本号
        springboot                         :'2.4.1', // SpringBoot版本号
        junit                              :'5.7.1', // 配置JUnit测试工具的版本编号
        junitPlatformLauncher              :'1.7.1',  // JUnit测试工具运行平台版本编号
        lombok                             :'1.18.18', // Lombok插件对应的版本号
        fastjson                           : '1.2.75', // FastJSON组件对应的版本号
]
ext.libraries = [   // 定义所有的依赖库
        // 以下的配置为SpringBoot项目所需要的核心依赖
        'spring-boot-gradle-plugin': "org.springframework.boot:spring-boot-gradle-plugin:${versions.springboot}",
        // 以下的配置为与项目用例测试有关的依赖
        'junit-jupiter-api': "org.junit.jupiter:junit-jupiter-api:${versions.junit}",
        'junit-vintage-engine': "org.junit.vintage:junit-vintage-engine:${versions.junit}",
        'junit-jupiter-engine': "org.junit.jupiter:junit-jupiter-engine:${versions.junit}",
        'junit-platform-launcher': "org.junit.platform:junit-platform-launcher:${versions.junitPlatformLauncher}",
        'junit-bom': "org.junit:junit-bom:${versions.junit}",
        // 以下的配置为Lombok组件有关的依赖
        'lombok': "org.projectlombok:lombok:${versions.lombok}",
        // 以下的配置为FastJSON组件有关的依赖
        'fastjson': "com.alibaba:fastjson:${versions.fastjson}"
]

3、
project('microboot-web') { // 子模块
    dependencies { // 配置子模块依赖
        compile(project(':microboot-common')) // 引入其他子模块
        compile(libraries.'fastjson') // 引入FastJSON组件
    }
}


4、
package com.yootk.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.List;

@Configuration // 必须明确的配置此类为配置类
public class WebConfig implements WebMvcConfigurer { // 进行WEB配置
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 1、默认在SpringBoot里面所提供的转换器为Jackson组件,那么首先要移除这个组件
        for (int x = 0; x < converters.size(); x ++) {  // 循环所有的转换器
            if (converters.get(x) instanceof MappingJackson2HttpMessageConverter) {
                converters.remove(x); // 删除当前的转换器
            }
        }
        // 2、项目之中一定是需要提供有一个转换器的,所以此时就可以将FastJSON转换器配置到项目之中
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        // 3、FastJSON在进行最终消息转换处理的时候实际上是需要进行相关配置定义的
        FastJsonConfig config = new FastJsonConfig(); // FastJSON配置
        config.setSerializerFeatures(
                SerializerFeature.WriteMapNullValue, // 允许Map的内容为null
                SerializerFeature.WriteNullListAsEmpty, // List集合为null则使用“[]”代替
                SerializerFeature.WriteNullStringAsEmpty, // String内容为空使用空字符串代替
                SerializerFeature.WriteDateUseDateFormat, // 日期格式化输出
                SerializerFeature.WriteNullNumberAsZero, // 数字为空使用0表示
                SerializerFeature.DisableCircularReferenceDetect // 禁用循环引用
        ); // 配置相关的序列化处理操作
        fastJsonHttpMessageConverter.setFastJsonConfig(config); // 配置FastJSON转换处理
        // 4、既然最终要输出的内容是JSON,所以需要配置好响应的头信息结构
        List<MediaType> fastjsonMediaTypes = new ArrayList<>(); // 定义所有的响应类型
        fastjsonMediaTypes.add(MediaType.APPLICATION_JSON); // 使用JSON的类型进行响应
        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastjsonMediaTypes);
        // 5、在转换器列表之中添加当前配置完成的FastJSON转换组件
        converters.add(fastJsonHttpMessageConverter);
    }
}

5、

package com.yootk.vo;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;

import java.util.Date;
@Data // 只要使用Lombok组件,99%的情况下就使用这一个注解
public class Message {
    private String title; // 字符串的参数
    @JSONField(format = "yyyy年MM月dd日") // FastJSON组件所提供的转换格式
    private Date pubdate; // 日期参数
    private String content;
}

6、localhost:8080/message/echo?title=沐言科技&content=www.yootk.com&pubdate=1998-09-19

7、

buildscript { 						// 定义脚本使用资源
    apply from: 'dependencies.gradle' // 引入所需要的依赖库文件
    repositories { 						// 脚本资源仓库
        maven { url 'https://maven.aliyun.com/repository/public' }
    }
    dependencies { 						// 依赖库
        classpath libraries.'spring-boot-gradle-plugin'
    }
}

通过 Features 配置序列化和反序列化的行为

1. Feature 介绍

在 fastjson 2.x 中,有两个 Feature,分别用来配置序列化和反序列化的行为。

  • JSONWriter.Feature 配置序列化的行为
  • JSONReader.Feature 配置反序列化的行为
2. 在 JSON 的 toJSONString 和 parse 方法中使用 Feature

2.1 在 JSON 的 toJSONString 方法中使用 JSONWriter.Feature

Bean bean = ...;
JSON.toJSONString(bean, JSONWriter.Feature.WriteNulls); // 输出对象中值为null的字段
2.2 在 JSON 的 parse 方法中使用 JSONReader.Feature
String jsonStr = ...;
JSON.parseObject(jsonStr, JSONReader.Feature.UseBigDecimalForDoubles); // 将小数数值读取为double
3. 在 JSONField 和 JSONType 上配置 features
class Model {
    @JSONField(serializeFeatures = JSONWriter.Feature.BrowserCompatible)
    public long value;
}
***

4. JSONReader.Feature 介绍
JSONReader.Feature介绍
FieldBased基于字段反序列化,如果不配置,会默认基于 public 的 field 和 getter 方法序列化。配置后,会基于非 static 的 field(包括 private)做反序列化。在 fieldbase 配置下会更安全
IgnoreNoneSerializable反序列化忽略非 Serializable 类型的字段
SupportArrayToBean支持数据映射的方式
InitStringFieldAsEmpty初始化 String 字段为空字符串""
SupportAutoType支持自动类型,要读取带"@type"类型信息的 JSON 数据,需要显式打开 SupportAutoType
SupportSmartMatch默认下是 camel case 精确匹配,打开这个后,能够智能识别 camel/upper/pascal/snake/Kebab 五中 case
UseNativeObject默认是使用 JSONObject 和 JSONArray,配置后会使用 LinkedHashMap 和 ArrayList
SupportClassForName支持类型为 Class 的字段,使用 Class.forName。为了安全这个是默认关闭的
IgnoreSetNullValue忽略输入为 null 的字段
UseDefaultConstructorAsPossible尽可能使用缺省构造函数,在 fieldBase 打开这个选项没打开的时候,会可能用 Unsafe.allocateInstance 来实现
UseBigDecimalForFloats默认配置会使用 BigDecimal 来 parse 小数,打开后会使用 Float
UseBigDecimalForDoubles默认配置会使用 BigDecimal 来 parse 小数,打开后会使用 Double
ErrorOnEnumNotMatch默认 Enum 的 name 不匹配时会忽略,打开后不匹配会抛异常
TrimString对读取到的字符串值做 trim 处理
ErrorOnNotSupportAutoType遇到 AutoType 报错(缺省是忽略)
DuplicateKeyValueAsArray重复 Key 的 Value 不是替换而是组合成数组
AllowUnQuotedFieldNames支持不带双引号的字段名
NonStringKeyAsString非 String 类型的 Key 当做 String 处理
Base64StringAsByteArray将 byte[]序列化为 Base64 格式的字符串
5. JSONWriter.Feature 介绍
JSONWriter.Feature介绍
FieldBased基于字段序列化,如果不配置,会默认基于 public 的 field 和 getter 方法序列化。配置后,会基于非 static 的 field(包括 private)做序列化。
IgnoreNoneSerializable序列化忽略非 Serializable 类型的字段
BeanToArray将对象序列为[101,"XX"]这样的数组格式,这样的格式会更小
WriteNulls序列化输出空值字段
BrowserCompatible在大范围超过 JavaScript 支持的整数,输出为字符串格式
NullAsDefaultValue将空置输出为缺省值,Number 类型的 null 都输出为 0,String 类型的 null 输出为"",数组和 Collection 类型的输出为[]
WriteBooleanAsNumber将 true 输出为 1,false 输出为 0
WriteNonStringValueAsString将非 String 类型的值输出为 String,不包括对象和数据类型
WriteClassName序列化时输出类型信息
NotWriteRootClassName打开 WriteClassName 的同时,不输出根对象的类型信息
NotWriteHashMapArrayListClassName打开 WriteClassName 的同时,不输出类型为 HashMap/ArrayList 类型对象的类型信息,反序列结合 UseNativeObject 使用,能节省序列化结果的大小
NotWriteDefaultValue当字段的值为缺省值时,不输出,这个能节省序列化后结果的大小
WriteEnumsUsingName序列化 enum 使用 name
WriteEnumUsingToString序列化 enum 使用 toString 方法
IgnoreErrorGetter忽略 setter 方法的错误
PrettyFormat格式化输出
ReferenceDetection打开引用检测,这个缺省是关闭的,和 fastjson 1.x 不一致
WriteNameAsSymbol将字段名按照 symbol 输出,这个仅在 JSONB 下起作用
WriteBigDecimalAsPlain序列化 BigDecimal 使用 toPlainString,避免科学计数法
UseSingleQuotes使用单引号
MapSortField对 Map 中的 KeyValue 按照 Key 做排序后再输出。在有些验签的场景需要使用这个 Feature
WriteNullListAsEmpty将 List 类型字段的空值序列化输出为空数组"[]"
WriteNullStringAsEmpty将 String 类型字段的空值序列化输出为空字符串""
WriteNullNumberAsZero将 Number 类型字段的空值序列化输出为 0
WriteNullBooleanAsFalse将 Boolean 类型字段的空值序列化输出为 false
NotWriteEmptyArray数组类型字段当 length 为 0 时不输出
WriteNonStringKeyAsString将 Map 中的非 String 类型的 Key 当做 String 类型输出
ErrorOnNoneSerializable序列化非 Serializable 对象时报错
WritePairAsJavaBean将 Apache Common 包中的 Pair 对象当做 JavaBean 序列化
BrowserSecure浏览器安全,将会'<' '>' '(' ')'字符做转义输出
WriteLongAsString将 Long 序列化为 String
WriteEnumUsingOrdinal序列化 Enum 使用 Ordinal,缺省是 name
WriteThrowableClassName序列化 Throwable 时带上类型信息
LargeObject这个是一个保护措施,是为了防止序列化有循环引用对象消耗过大资源的保护措施。
UnquoteFieldName不带引号输出 Key
NotWriteSetClassName当打开 WriteClassName 时又不想输出 Set 的类型信息,使用这个 Feature
NotWriteNumberClassName当打开 WriteClassName 时又不想输出 Number 的类型信息,比如 L/S/B/F/D 这种后缀,使用这个 Feature

返回 XML 数据

XML 响应

  • 在现代项目开发中对于 WEB 接口设计来讲往往返回的都是基于 Rest 架构的 JSON 数据信息,以常见的前后端分离设计结构为例,前端项目使用特定的后端接口获取 JSON 数据并进行显示填充
  • 但是在一些老旧的系统中依然是以 XML 方式实现数据交互的
1、
// https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.12.2'
// https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.16.2'


// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.2'

// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.12.2'

// https://mvnrepository.com/artifact/jakarta.xml.bind/jakarta.xml.bind-api
implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '4.0.1'


2、
ext.versions = [    // 定义所有要使用的版本号
        springboot                         :'2.4.3', // SpringBoot版本号
        junit                              :'5.7.1', // 配置JUnit测试工具的版本编号
        junitPlatformLauncher              :'1.7.1',  // JUnit测试工具运行平台版本编号
        lombok                             :'1.18.18', // Lombok插件对应的版本号
        fastjson                           : '1.2.75', // FastJSON组件对应的版本号
        jackson                            : '2.12.2', // 配置Jackson相关依赖库
]
ext.libraries = [   // 定义所有的依赖库
        // 以下的配置为SpringBoot项目所需要的核心依赖
        'spring-boot-gradle-plugin': "org.springframework.boot:spring-boot-gradle-plugin:${versions.springboot}",
        // 以下的配置为与项目用例测试有关的依赖
        'junit-jupiter-api': "org.junit.jupiter:junit-jupiter-api:${versions.junit}",
        'junit-vintage-engine': "org.junit.vintage:junit-vintage-engine:${versions.junit}",
        'junit-jupiter-engine': "org.junit.jupiter:junit-jupiter-engine:${versions.junit}",
        'junit-platform-launcher': "org.junit.platform:junit-platform-launcher:${versions.junitPlatformLauncher}",
        'junit-bom': "org.junit:junit-bom:${versions.junit}",
        // 以下的配置为Lombok组件有关的依赖
        'lombok': "org.projectlombok:lombok:${versions.lombok}",
        // 以下的配置为FastJSON组件有关的依赖
        'fastjson': "com.alibaba:fastjson:${versions.fastjson}",
        // 以下的配置为Jackson将输出转换为XML有关的依赖
        'jackson-dataformat-xml': "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${versions.jackson}",
        'jackson-databind': "com.fasterxml.jackson.core:jackson-databind:${versions.jackson}",
        'jackson-annotations': "com.fasterxml.jackson.core:jackson-annotations:${versions.jackson}",
]


3、
package com.yootk.vo;

import lombok.Data;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Date;
@Data // 只要使用Lombok组件,99%的情况下就使用这一个注解
@XmlRootElement // 配置XML根元素
public class Message {
    @XmlElement
    private String title; // 字符串的参数
    @XmlElement
    private Date pubdate; // 日期参数
    @XmlElement
    private String content;
}

4、
localhost:8080/message/xml?title=沐言科技&content=www.yootk.com&pubdate=1998-09-19

返回 PDF 数据

PDF

  • PDF(Portable Document Format、可携带文档格式)是一种与操作系统无关的电子文件格式,可以有效支持多媒体集成信息,将文字、格式以及图形图像封装在一个文之中,同时也支持特长文件的存储避免了不同的文本编辑器所造成的文本显示格式错乱的问题,在 Java 项目中 itextpdf 组件比较常见的 PDF 创建工具。
1、
// https://mvnrepository.com/artifact/com.itextpdf/itextpdf
implementation group: 'com.itextpdf', name: 'itextpdf', version: '5.5.13.2'
// https://mvnrepository.com/artifact/com.itextpdf/itextpdf
implementation group: 'com.itextpdf', name: 'itextpdf', version: '5.5.13.3'


2、
ext.versions = [    // 定义所有要使用的版本号
        springboot                           :'2.4.3', // SpringBoot版本号
        junit                               :'5.7.1', // 配置JUnit测试工具的版本编号
        junitPlatformLauncher               :'1.7.1',  // JUnit测试工具运行平台版本编号
        lombok                              :'1.18.18', // Lombok插件对应的版本号
        fastjson                            : '1.2.75', // FastJSON组件对应的版本号
        jackson                             : '2.12.2', // 配置Jackson相关依赖库
        itextpdf                            : '5.5.13.2', // PDF文件生成的依赖库
]
ext.libraries = [   // 定义所有的依赖库
        // 以下的配置为SpringBoot项目所需要的核心依赖
        'spring-boot-gradle-plugin': "org.springframework.boot:spring-boot-gradle-plugin:${versions.springboot}",
        // 以下的配置为与项目用例测试有关的依赖
        'junit-jupiter-api': "org.junit.jupiter:junit-jupiter-api:${versions.junit}",
        'junit-vintage-engine': "org.junit.vintage:junit-vintage-engine:${versions.junit}",
        'junit-jupiter-engine': "org.junit.jupiter:junit-jupiter-engine:${versions.junit}",
        'junit-platform-launcher': "org.junit.platform:junit-platform-launcher:${versions.junitPlatformLauncher}",
        'junit-bom': "org.junit:junit-bom:${versions.junit}",
        // 以下的配置为Lombok组件有关的依赖
        'lombok': "org.projectlombok:lombok:${versions.lombok}",
        // 以下的配置为FastJSON组件有关的依赖
        'fastjson': "com.alibaba:fastjson:${versions.fastjson}",
        // 以下的配置为Jackson将输出转换为XML有关的依赖
        'jackson-dataformat-xml': "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${versions.jackson}",
        'jackson-databind': "com.fasterxml.jackson.core:jackson-databind:${versions.jackson}",
        'jackson-annotations': "com.fasterxml.jackson.core:jackson-annotations:${versions.jackson}",
        // 以下的配置为ITextPDF输出的有关依赖配置
        'itextpdf': "com.itextpdf:itextpdf:${versions.itextpdf}",
]

3、
project('microboot-web') { // 子模块
    dependencies { // 配置子模块依赖
        compile(project(':microboot-common')) // 引入其他子模块
        compile(libraries.'itextpdf') // 引入PDF相关依赖
    }
}


4、

package com.yootk.action;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;

@Controller // 使用的是普通的控制器的注解
@RequestMapping("/data/*")
public class PDFAction {
    @GetMapping("pdf") // 配置映射路径
    public void createPDFData(HttpServletResponse response) throws Exception { // 使用Response是为了响应处理
        response.setHeader("Content-Type", "application/pdf"); // 设置响应类型
        // 一般情况下可以将是生成的PDF文件进行下载,所以此时强制性的开启下载,并且配置下载文件名称
        response.setHeader("Content-Disposition", "attachement;filename=yootk.pdf");
        // 下面开始使用ITextPDF组件来在内存之中形成一份要生成的PDF文件
        Document document = new Document(PageSize.A4, 10, 10, 50, 20); // 主要是设置页面的大小
        PdfWriter.getInstance(document, response.getOutputStream()); // 获取PDF的输出流配置
        document.open(); // 开始构建PDF文档内容
        // 在当前的程序里面已经提供了图片的资源,所以利用资源匹配符进行资源路径定义
        Resource imageResource = new ClassPathResource("/images/muyan_yootk_share.png"); // Spring所提供的资源访问
        Image image = Image.getInstance(imageResource.getFile().getAbsolutePath()); // 通过指定的路径加载图片
        // PDF文件在进行生成的时候是基于坐标的方式实现的绘制处理
        image.scaleToFit(PageSize.A4.getWidth() / 2, PageSize.A4.getHeight());
        float pointX = (PageSize.A4.getWidth() - image.getScaledWidth()) / 2;
        float pointY = PageSize.A4.getHeight() - image.getHeight() - 100;
        image.setAbsolutePosition(pointX, pointY); // 绘制坐标的定义
        document.add(image); // 开始追加图片到文档之中
        document.add(new Paragraph("\n\n\n")); // 图片之后换三行而后输出文字信息
        // 如果要想输出文字,而且要想输出正常的中文,就必须设置有字库
        Resource fontResource = new ClassPathResource("/fonts/Alibaba-PuHuiTi-Bold.ttf"); // 字体的资源
        BaseFont baseFont = BaseFont.createFont(fontResource.getFile().getAbsolutePath(),
                BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        Font font = new Font(baseFont, 20, Font.NORMAL); // 定义要使用的字库
        // 在PDF文件上开始绘制文本信息
        String titles[] = new String[] {"沐言科技", "李兴华编程训练营", "人人分享公益直播"};
        String contents [] = new String[] {"www.yootk.com", "edu.yootk.com", "share.yootk.com"};
        for (int x = 0; x < titles.length; x++) {   // 实现数据的循环输出
            PdfPTable table = new PdfPTable(2); // 定义表格
            PdfPCell cell = new PdfPCell(); // 创建单元格信息
            cell.setPhrase(new Paragraph(titles[x], font)); // 输出文字定义
            table.addCell(cell); // 追加单元格
            cell = new PdfPCell();
            cell.setPhrase(new Paragraph(contents[x]));
            table.addCell(cell);
            document.add(table);
        }
        document.close();
    }
}


5、localhost:8080/data/pdf

返回 Excel 数据

1、
// https://mvnrepository.com/artifact/cn.afterturn/easypoi-spring-boot-starter
implementation group: 'cn.afterturn', name: 'easypoi-spring-boot-starter', version: '4.3.0'
// https://mvnrepository.com/artifact/cn.afterturn/easypoi-spring-boot-starter
implementation group: 'cn.afterturn', name: 'easypoi-spring-boot-starter', version: '4.5.0'


2、
ext.versions = [    // 定义所有要使用的版本号
        springboot                          : '2.4.3', // SpringBoot版本号
        junit                               : '5.7.1', // 配置JUnit测试工具的版本编号
        junitPlatformLauncher               : '1.7.1',  // JUnit测试工具运行平台版本编号
        lombok                              : '1.18.18', // Lombok插件对应的版本号
        fastjson                            : '1.2.75', // FastJSON组件对应的版本号
        jackson                             : '2.12.2', // 配置Jackson相关依赖库
        itextpdf                            : '5.5.13.2', // PDF文件生成的依赖库
        easypoi                             : '4.3.0', // 生成Excel处理的依赖库
]
ext.libraries = [   // 定义所有的依赖库
        // 以下的配置为SpringBoot项目所需要的核心依赖
        'spring-boot-gradle-plugin': "org.springframework.boot:spring-boot-gradle-plugin:${versions.springboot}",
        // 以下的配置为与项目用例测试有关的依赖
        'junit-jupiter-api': "org.junit.jupiter:junit-jupiter-api:${versions.junit}",
        'junit-vintage-engine': "org.junit.vintage:junit-vintage-engine:${versions.junit}",
        'junit-jupiter-engine': "org.junit.jupiter:junit-jupiter-engine:${versions.junit}",
        'junit-platform-launcher': "org.junit.platform:junit-platform-launcher:${versions.junitPlatformLauncher}",
        'junit-bom': "org.junit:junit-bom:${versions.junit}",
        // 以下的配置为Lombok组件有关的依赖
        'lombok': "org.projectlombok:lombok:${versions.lombok}",
        // 以下的配置为FastJSON组件有关的依赖
        'fastjson': "com.alibaba:fastjson:${versions.fastjson}",
        // 以下的配置为Jackson将输出转换为XML有关的依赖
        'jackson-dataformat-xml': "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${versions.jackson}",
        'jackson-databind': "com.fasterxml.jackson.core:jackson-databind:${versions.jackson}",
        'jackson-annotations': "com.fasterxml.jackson.core:jackson-annotations:${versions.jackson}",
        // 以下的配置为ITextPDF输出的有关依赖配置
        'itextpdf': "com.itextpdf:itextpdf:${versions.itextpdf}",
        // 以下的配置为生成Excel文件有关的依赖配置
        'easypoi-spring-boot-starter': "cn.afterturn:easypoi-spring-boot-starter:${versions.easypoi}"
]

3、
project('microboot-web') { // 子模块
    dependencies { // 配置子模块依赖
        compile(project(':microboot-common')) // 引入其他子模块
        compile(libraries.'itextpdf') // 引入PDF相关依赖
        compile(libraries.'easypoi-spring-boot-starter') // 引入EasyPOI组件
    }
}


4、
package com.yootk.vo;

import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;

import java.util.Date;
@Data // 只要使用Lombok组件,99%的情况下就使用这一个注解
public class Message {
    @Excel(name = "信息标题", orderNum = "0", width = 30) // 生成Excel表格列的配置
    private String title; // 字符串的参数
    @Excel(name = "信息日期", orderNum = "1", width = 50) // 生成Excel表格列的配置
    private Date pubdate; // 日期参数
    @Excel(name = "信息内容", orderNum = "2", width = 100) // 生成Excel表格列的配置
    private String content;
}


5、

package com.yootk.action;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.export.ExcelExportService;
import com.yootk.vo.Message;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Controller // 使用的是普通的控制器的注解
@RequestMapping("/data/*")
public class ExcelAction {
    @GetMapping("excel") // 配置映射路径
    public void createExcelData(HttpServletResponse response) throws Exception { // 使用Response是为了响应处理
        response.setHeader("Content-Type",
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 设置响应类型
        response.setHeader("Content-Disposition", "attachement;filename=yootk.xls");
        // 随后通过一些固定数据的循环方式来生成相应的Excel数据
        String titles[] = new String[] {"沐言科技", "李兴华编程训练营", "人人分享公益直播"};
        String contents [] = new String[] {"www.yootk.com", "edu.yootk.com", "share.yootk.com"};
        // 数据的生成需要将数据保存在Message类的对象之中
        List<Message> messageList = new ArrayList<>(); // 定义数据的保存集合
        for (int x = 0; x < titles.length; x++) {
            Message message = new Message();
            message.setTitle(titles[x]);
            message.setContent(contents[x]);
            message.setPubdate(new Date());
            messageList.add(message); // 将数据添加到集合之中
        }
        // 随后要开始进行XLS文件内容的配置了
        ExportParams exportParams = new ExportParams("沐言科技消息管理", "最新消息", ExcelType.XSSF);
        Workbook workbook = new XSSFWorkbook(); // 创建工作薄
        new ExcelExportService().createSheet(workbook, exportParams, Message.class, messageList);
        workbook.write(response.getOutputStream());
    }
}

localhost:8080/data/excel

demo


上次编辑于: