SpringBoot實現(xiàn)Word和PDF互相轉(zhuǎn)換的操作詳解
第一章:Word和PDF的“愛恨情仇”
1.1 初遇:兩種不同的“性格”
Word同學(xué):活潑開朗的編輯小王子,天生愛打扮(格式豐富),隨時可以改頭換面(可編輯),但有時候過于花哨,換個環(huán)境就“水土不服”。
PDF同學(xué):高冷嚴謹?shù)臋n案管理員,保持原樣絕不動搖(格式固定),去哪都一個樣(跨平臺一致),但有點固執(zhí)——“你可以看我,但別想碰我”(難以編輯)。
1.2 辦公室戀情發(fā)展
- Word轉(zhuǎn)PDF:Word決定“從良”,放棄花哨生活,變成穩(wěn)重可靠的PDF。這叫“愛的封印”——把美好定格,防止別人亂改。
- PDF轉(zhuǎn)Word:PDF想要“放開自我”,嘗試可編輯的生活。但這個過程就像“開盲盒”——有時候能完美轉(zhuǎn)換,有時候……只能說“盡力了”。
第二章:SpringBoot當“紅娘”的準備步驟
2.1 創(chuàng)建SpringBoot“婚介所”
用Spring Initializr創(chuàng)建項目,記得帶上這些“彩禮”:
- Spring Web (提供REST API)
- Apache POI (處理Word)
- PDFBox (處理PDF)
- OpenPDF (或iText,用于PDF生成)
2.2 Maven依賴配置(pom.xml)
<!-- 婚禮請柬列表 -->
<dependencies>
<!-- SpringBoot基礎(chǔ)套餐 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Word處理專家:Apache POI全家桶 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<!-- PDF處理專家:PDFBox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.27</version>
</dependency>
<!-- 另一種PDF生成選擇:OpenPDF -->
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
<version>1.3.30</version>
</dependency>
</dependencies>
第三章:詳細實現(xiàn)步驟(帶完整代碼)
3.1 Word轉(zhuǎn)PDF:Word的“成熟儀式”
創(chuàng)建Word處理服務(wù)
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.stereotype.Service;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import com.lowagie.text.*;
import com.lowagie.text.pdf.PdfWriter;
import java.io.*;
@Service
public class WordToPdfService {
/**
* 方法1:使用Apache POI + OpenPDF(適合.doc和.docx)
* 這是我們的“豪華版”轉(zhuǎn)換,帶格式的
*/
public void convertWordToPdf(InputStream wordStream, OutputStream pdfStream)
throws Exception {
// 1. 讀取Word文檔(就像給Word做體檢)
XWPFDocument document = new XWPFDocument(wordStream);
// 2. 創(chuàng)建PDF文檔(準備新衣服)
Document pdfDocument = new Document();
PdfWriter.getInstance(pdfDocument, pdfStream);
pdfDocument.open();
// 3. 逐段處理(把Word的每一句話翻譯成PDF能聽懂的語言)
for (XWPFParagraph paragraph : document.getParagraphs()) {
String text = paragraph.getText();
if (!text.isEmpty()) {
// 設(shè)置字體大?。≒DF比較挑剔,要明確告訴它)
Font font = new Font(Font.HELVETICA, 12);
pdfDocument.add(new Paragraph(text, font));
}
}
// 4. 處理表格(如果有的話)
for (XWPFTable table : document.getTables()) {
// 這里可以添加表格處理邏輯
// 為了簡化,我們先跳過復(fù)雜的表格轉(zhuǎn)換
}
// 5. 完成轉(zhuǎn)換(禮成?。?
pdfDocument.close();
document.close();
}
/**
* 方法2:快速轉(zhuǎn)換版(只提取文本,適合簡單文檔)
* 這是“經(jīng)濟適用型”轉(zhuǎn)換
*/
public void convertWordToPdfSimple(File wordFile, File pdfFile)
throws IOException {
XWPFDocument doc = new XWPFDocument(new FileInputStream(wordFile));
try (PDDocument pdfDoc = new PDDocument()) {
PDPage page = new PDPage();
pdfDoc.addPage(page);
try (PDPageContentStream contentStream =
new PDPageContentStream(pdfDoc, page)) {
contentStream.beginText();
contentStream.setFont(PDType1Font.HELVETICA, 12);
contentStream.newLineAtOffset(50, 700);
// 逐段添加文本
for (XWPFParagraph para : doc.getParagraphs()) {
String text = para.getText();
if (!text.trim().isEmpty()) {
contentStream.showText(text);
contentStream.newLineAtOffset(0, -15); // 換行
}
}
contentStream.endText();
}
pdfDoc.save(pdfFile);
}
doc.close();
}
}
創(chuàng)建REST控制器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
@RestController
@RequestMapping("/api/document")
public class DocumentConversionController {
@Autowired
private WordToPdfService wordToPdfService;
/**
* Word轉(zhuǎn)PDF的API端點
* 訪問方式:POST /api/document/word-to-pdf
*/
@PostMapping("/word-to-pdf")
public ResponseEntity<byte[]> convertWordToPdf(
@RequestParam("file") MultipartFile file) {
try {
// 1. 檢查文件類型(確保不是亂來的文件)
String filename = file.getOriginalFilename();
if (filename == null ||
(!filename.endsWith(".docx") && !filename.endsWith(".doc"))) {
return ResponseEntity.badRequest()
.body("只能上傳.doc或.docx文件!".getBytes());
}
// 2. 創(chuàng)建臨時文件(給Word和PDF準備臨時婚房)
File tempWordFile = File.createTempFile("temp", ".docx");
File tempPdfFile = File.createTempFile("converted", ".pdf");
// 3. 保存上傳的文件
file.transferTo(tempWordFile);
// 4. 執(zhí)行轉(zhuǎn)換(見證奇跡的時刻?。?
wordToPdfService.convertWordToPdfSimple(
tempWordFile, tempPdfFile);
// 5. 讀取生成的PDF
byte[] pdfBytes = Files.readAllBytes(tempPdfFile.toPath());
// 6. 設(shè)置響應(yīng)頭(告訴瀏覽器:這是PDF,請用PDF方式打開)
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF);
headers.setContentDisposition(
ContentDisposition.attachment()
.filename(filename.replace(".docx", ".pdf").replace(".doc", ".pdf"))
.build()
);
// 7. 清理臨時文件(婚房不能留著,要環(huán)保)
tempWordFile.delete();
tempPdfFile.delete();
return new ResponseEntity<>(pdfBytes, headers, HttpStatus.OK);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(("轉(zhuǎn)換失?。? + e.getMessage()).getBytes());
}
}
}
3.2 PDF轉(zhuǎn)Word:PDF的“解放運動”
創(chuàng)建PDF轉(zhuǎn)Word服務(wù)
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.stereotype.Service;
import java.io.*;
@Service
public class PdfToWordService {
/**
* PDF轉(zhuǎn)Word - 文本提取版
* 警告:這就像把煎蛋變回雞蛋——能變,但樣子不一樣了
*/
public void convertPdfToWord(File pdfFile, File wordFile) throws IOException {
// 1. 讀取PDF(撬開PDF的嘴,讓它說話)
try (PDDocument document = PDDocument.load(pdfFile)) {
// 2. 創(chuàng)建Word文檔(準備新容器)
XWPFDocument wordDoc = new XWPFDocument();
// 3. 提取PDF文本(讓PDF"吐"出文字)
PDFTextStripper stripper = new PDFTextStripper();
String text = stripper.getText(document);
// 4. 按行分割并添加到Word
String[] lines = text.split("\n");
for (String line : lines) {
if (!line.trim().isEmpty()) {
XWPFParagraph paragraph = wordDoc.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText(line);
run.setFontSize(12);
}
}
// 5. 保存Word文檔(完成轉(zhuǎn)換)
try (FileOutputStream out = new FileOutputStream(wordFile)) {
wordDoc.write(out);
}
wordDoc.close();
}
}
/**
* 高級版:帶基本格式保留
* 注意:PDF轉(zhuǎn)Word是"世界難題",不要期待完美
*/
public void convertPdfToWordAdvanced(InputStream pdfStream,
OutputStream wordStream)
throws IOException {
try (PDDocument pdfDoc = PDDocument.load(pdfStream);
XWPFDocument wordDoc = new XWPFDocument()) {
PDFTextStripper stripper = new PDFTextStripper();
// 設(shè)置提取參數(shù)
stripper.setSortByPosition(true); // 按位置排序
stripper.setStartPage(1); // 從第1頁開始
stripper.setEndPage(pdfDoc.getNumberOfPages()); // 到最后一頁
String text = stripper.getText(pdfDoc);
// 處理文本,嘗試保留一些結(jié)構(gòu)
String[] paragraphs = text.split("\n\n"); // 假設(shè)空行是段落分隔
for (String paraText : paragraphs) {
if (paraText.trim().length() > 0) {
XWPFParagraph paragraph = wordDoc.createParagraph();
// 設(shè)置段落格式
paragraph.setAlignment(ParagraphAlignment.LEFT);
// 添加文本
XWPFRun run = paragraph.createRun();
run.setText(paraText);
run.setFontFamily("宋體");
run.setFontSize(12);
// 添加空行作為段落間隔
wordDoc.createParagraph();
}
}
wordDoc.write(wordStream);
}
}
}
添加PDF轉(zhuǎn)Word的API端點
// 在DocumentConversionController中添加
@PostMapping("/pdf-to-word")
public ResponseEntity<byte[]> convertPdfToWord(
@RequestParam("file") MultipartFile file) {
try {
// 1. 檢查文件類型
String filename = file.getOriginalFilename();
if (filename == null || !filename.endsWith(".pdf")) {
return ResponseEntity.badRequest()
.body("只能上傳.pdf文件!".getBytes());
}
// 2. 創(chuàng)建臨時文件
File tempPdfFile = File.createTempFile("temp", ".pdf");
File tempWordFile = File.createTempFile("converted", ".docx");
// 3. 保存上傳的文件
file.transferTo(tempPdfFile);
// 4. 執(zhí)行轉(zhuǎn)換(讓PDF"變身")
PdfToWordService pdfToWordService = new PdfToWordService();
pdfToWordService.convertPdfToWord(tempPdfFile, tempWordFile);
// 5. 讀取生成的Word
byte[] wordBytes = Files.readAllBytes(tempWordFile.toPath());
// 6. 設(shè)置響應(yīng)頭
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDisposition(
ContentDisposition.attachment()
.filename(filename.replace(".pdf", ".docx"))
.build()
);
// 7. 清理臨時文件
tempPdfFile.delete();
tempWordFile.delete();
return new ResponseEntity<>(wordBytes, headers, HttpStatus.OK);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(("轉(zhuǎn)換失?。? + e.getMessage()).getBytes());
}
}
3.3 創(chuàng)建前端頁面(HTML + JavaScript)
<!DOCTYPE html>
<html>
<head>
<title>文檔轉(zhuǎn)換器 - Word和PDF的相親平臺</title>
<style>
body {
font-family: 'Comic Sans MS', cursive, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}
.container {
background: white;
padding: 30px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
h1 {
color: #2c3e50;
text-align: center;
margin-bottom: 30px;
}
.converter-box {
border: 2px dashed #3498db;
padding: 20px;
border-radius: 10px;
margin: 20px 0;
text-align: center;
transition: all 0.3s;
}
.converter-box:hover {
border-color: #e74c3c;
background: #f9f9f9;
}
button {
background: #3498db;
color: white;
border: none;
padding: 12px 24px;
border-radius: 25px;
cursor: pointer;
font-size: 16px;
margin: 10px;
transition: all 0.3s;
}
button:hover {
background: #2980b9;
transform: translateY(-2px);
}
#result {
margin-top: 20px;
padding: 15px;
background: #ecf0f1;
border-radius: 5px;
display: none;
}
.tips {
background: #fff3cd;
border-left: 4px solid #ffc107;
padding: 15px;
margin: 20px 0;
border-radius: 0 5px 5px 0;
}
</style>
</head>
<body>
<div class="container">
<h1>?? Word ? PDF 轉(zhuǎn)換器 ??</h1>
<p>讓W(xué)ord和PDF愉快地"談戀愛"!選擇你想進行的轉(zhuǎn)換:</p>
<div class="tips">
<strong>溫馨提示:</strong>
1. Word轉(zhuǎn)PDF:婚禮很完美,格式基本保留
2. PDF轉(zhuǎn)Word:離婚再結(jié)婚,可能損失一些"財產(chǎn)"(格式)
3. 文件大小限制:10MB以內(nèi)
</div>
<!-- Word轉(zhuǎn)PDF區(qū)域 -->
<div class="converter-box">
<h2>Word → PDF 轉(zhuǎn)換</h2>
<p>讓活潑的Word變成穩(wěn)重的PDF(推薦使用)</p>
<input type="file" id="wordFile" accept=".doc,.docx">
<button onclick="convertWordToPdf()">開始轉(zhuǎn)換!</button>
</div>
<!-- PDF轉(zhuǎn)Word區(qū)域 -->
<div class="converter-box">
<h2>PDF → Word 轉(zhuǎn)換</h2>
<p>嘗試讓高冷的PDF變得可編輯(結(jié)果可能"驚喜")</p>
<input type="file" id="pdfFile" accept=".pdf">
<button onclick="convertPdfToWord()">勇敢嘗試!</button>
</div>
<!-- 結(jié)果顯示區(qū)域 -->
<div id="result">
<h3>轉(zhuǎn)換結(jié)果</h3>
<p id="resultMessage"></p>
<a id="downloadLink" style="display:none;">
<button>下載轉(zhuǎn)換后的文件</button>
</a>
</div>
</div>
<script>
// Word轉(zhuǎn)PDF函數(shù)
async function convertWordToPdf() {
const fileInput = document.getElementById('wordFile');
const file = fileInput.files[0];
if (!file) {
alert('請先選擇一個Word文件!');
return;
}
const formData = new FormData();
formData.append('file', file);
try {
const response = await fetch('/api/document/word-to-pdf', {
method: 'POST',
body: formData
});
if (response.ok) {
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
document.getElementById('result').style.display = 'block';
document.getElementById('resultMessage').textContent =
'轉(zhuǎn)換成功!Word已成功"進化"為PDF!';
const downloadLink = document.getElementById('downloadLink');
downloadLink.href = url;
downloadLink.download = file.name.replace(/\.(docx|doc)$/, '.pdf');
downloadLink.style.display = 'block';
} else {
throw new Error('轉(zhuǎn)換失敗');
}
} catch (error) {
document.getElementById('result').style.display = 'block';
document.getElementById('resultMessage').textContent =
'轉(zhuǎn)換失?。? + error.message;
}
}
// PDF轉(zhuǎn)Word函數(shù)
async function convertPdfToWord() {
const fileInput = document.getElementById('pdfFile');
const file = fileInput.files[0];
if (!file) {
alert('請先選擇一個PDF文件!');
return;
}
const formData = new FormData();
formData.append('file', file);
try {
const response = await fetch('/api/document/pdf-to-word', {
method: 'POST',
body: formData
});
if (response.ok) {
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
document.getElementById('result').style.display = 'block';
document.getElementById('resultMessage').textContent =
'PDF成功"解放"為Word!部分格式可能丟失,請理解。';
const downloadLink = document.getElementById('downloadLink');
downloadLink.href = url;
downloadLink.download = file.name.replace('.pdf', '.docx');
downloadLink.style.display = 'block';
} else {
throw new Error('轉(zhuǎn)換失敗');
}
} catch (error) {
document.getElementById('result').style.display = 'block';
document.getElementById('resultMessage').textContent =
'轉(zhuǎn)換失?。? + error.message + '。PDF可能太"固執(zhí)"了!';
}
}
</script>
</body>
</html>
3.4 添加Application主類
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
@SpringBootApplication
public class DocumentConverterApplication {
public static void main(String[] args) {
SpringApplication.run(DocumentConverterApplication.class, args);
System.out.println("======================================");
System.out.println("文檔轉(zhuǎn)換服務(wù)啟動成功!");
System.out.println("訪問地址:http://localhost:8080");
System.out.println("Word和PDF可以開始'談戀愛'了!");
System.out.println("======================================");
}
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(10485760); // 10MB限制
resolver.setDefaultEncoding("UTF-8");
return resolver;
}
}
3.5 添加配置文件(application.yml)
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
application:
name: document-converter
server:
port: 8080
servlet:
context-path: /
# 日志配置,方便調(diào)試
logging:
level:
org.springframework.web: INFO
com.example.documentconverter: DEBUG
file:
name: logs/document-converter.log
第四章:項目優(yōu)化和高級功能
4.1 添加批量轉(zhuǎn)換功能
@Service
public class BatchConversionService {
/**
* 批量轉(zhuǎn)換 - 適合大量文檔處理
* 比如:把整個部門的Word報告都轉(zhuǎn)成PDF
*/
public void batchWordToPdf(List<File> wordFiles, File outputDir) {
wordFiles.parallelStream().forEach(wordFile -> {
try {
File pdfFile = new File(outputDir,
wordFile.getName().replaceFirst("\\.[^.]+$", "") + ".pdf");
// 調(diào)用轉(zhuǎn)換服務(wù)
// wordToPdfService.convertWordToPdfSimple(wordFile, pdfFile);
System.out.println("轉(zhuǎn)換完成: " + wordFile.getName());
} catch (Exception e) {
System.err.println("轉(zhuǎn)換失敗: " + wordFile.getName() + " - " + e.getMessage());
}
});
}
}
4.2 添加轉(zhuǎn)換進度跟蹤
@Component
public class ConversionProgressTracker {
private Map<String, ConversionStatus> statusMap = new ConcurrentHashMap<>();
public enum ConversionStatus {
PENDING, PROCESSING, COMPLETED, FAILED
}
public void startConversion(String taskId, String filename) {
statusMap.put(taskId, ConversionStatus.PROCESSING);
}
public void updateProgress(String taskId, int progress) {
// 更新進度
}
public ConversionStatus getStatus(String taskId) {
return statusMap.getOrDefault(taskId, ConversionStatus.PENDING);
}
}
4.3 添加水印功能
@Service
public class WatermarkService {
/**
* 給PDF添加水印
*/
public void addWatermarkToPdf(File pdfFile, String watermarkText)
throws IOException {
try (PDDocument document = PDDocument.load(pdfFile)) {
for (PDPage page : document.getPages()) {
try (PDPageContentStream contentStream =
new PDPageContentStream(document, page,
PDPageContentStream.AppendMode.APPEND, true)) {
// 設(shè)置水印樣式
contentStream.setFont(PDType1Font.HELVETICA_OBLIQUE, 60);
contentStream.setNonStrokingColor(200, 200, 200); // 淺灰色
// 旋轉(zhuǎn)45度
contentStream.beginText();
contentStream.setTextRotation(Math.toRadians(45),
page.getMediaBox().getWidth() / 2,
page.getMediaBox().getHeight() / 2);
contentStream.showText(watermarkText);
contentStream.endText();
}
}
document.save(pdfFile);
}
}
}
第五章:總結(jié)與心得
5.1 轉(zhuǎn)換效果對比
Word轉(zhuǎn)PDF:
- 成功率高,就像把新鮮水果做成果醬——能很好地保存原味
- 格式基本保留,布局不亂
- 推薦使用Apache POI + OpenPDF組合
PDF轉(zhuǎn)Word:
- 像把炒熟的雞蛋變回生雞蛋——技術(shù)上有難度
- 復(fù)雜格式(表格、特殊排版)容易丟失
- 掃描版PDF需要OCR,這是另一個故事了
5.2 實戰(zhàn)建議
選擇合適的工具庫:
- 簡單需求:Apache POI + PDFBox
- 復(fù)雜需求:考慮Aspose或商業(yè)庫(但要花錢)
- 云端方案:直接用Microsoft Graph API或Google Docs API
性能優(yōu)化建議:
- 大文件分塊處理
- 使用內(nèi)存映射文件
- 考慮異步處理 + WebSocket推送進度
錯誤處理要點:
- 一定要關(guān)閉文檔流(否則內(nèi)存泄漏)
- 添加文件類型驗證
- 設(shè)置合理的超時時間
安全注意事項:
- 限制上傳文件大小
- 檢查文件內(nèi)容(防止惡意文件)
- 臨時文件及時清理
5.3 結(jié)語
通過這個項目,我們成功地為Word和PDF搭建了一個"相親平臺":
- Word轉(zhuǎn)PDF就像一場浪漫的婚禮:Word穿上PDF的婚紗,承諾"從今以后,我的格式永不變心"。
- PDF轉(zhuǎn)Word則像一場冒險:PDF嘗試脫下嚴肅的外套,說"讓我也試試自由的感覺"。
以上就是SpringBoot實現(xiàn)Word和PDF互相轉(zhuǎn)換的操作詳解的詳細內(nèi)容,更多關(guān)于SpringBoot Word和PDF互轉(zhuǎn)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用Jackson實現(xiàn)Map與Bean互轉(zhuǎn)方式
這篇文章主要介紹了使用Jackson實現(xiàn)Map與Bean互轉(zhuǎn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
java中i18n的properties的亂碼問題及解決思路
解決java后臺返回給前端的500信息亂碼問題,通過開啟IDEA的Transparent native-to-ascii conversion編碼,使讀取i18n配置文件的信息顯示正常,此方法僅供參考2026-05-05
springboot內(nèi)置tomcat之NIO處理流程一覽
這篇文章主要介紹了springboot內(nèi)置tomcat之NIO處理流程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
Java中利用Alibaba開源技術(shù)EasyExcel來操作Excel表的示例代碼
這篇文章主要介紹了Java中利用Alibaba開源技術(shù)EasyExcel來操作Excel表的示例代碼,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03
使用Java Stream將集合轉(zhuǎn)換為一對一Map的方法詳解
在日常的開發(fā)工作中,我們經(jīng)常使用到Java Stream,特別是Stream API中提供的Collectors.toList()收集器,但有些場景下,我們需要將集合轉(zhuǎn)換為Map,所以本文就給大家介紹了如何使用Java Stream將集合轉(zhuǎn)換為一對一Map,需要的朋友可以參考下2025-12-12

