Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
天就給大家介紹幾款可以實現 PDF 轉換 Word 格式的免費在線工具,收藏了它們,你不再需要下載安裝,只需一個可以上網的瀏覽器,把PDF文檔上傳到網站,馬上就能轉換出 doc 或 docx、rtf 等 Office 格式的文檔了,相當的方便實用!如果這篇文章能幫上你的忙,或你的朋友有類似的需求,歡迎大家用各種方式擴散~~~
網站介紹
一.迅捷在線轉換
傳送門:http://app.xunjiepdf.com/
迅捷在線pdf轉word轉換器免費版為您提供將PDF轉換成WORD,word轉換成pdf,ppt轉換成pdf的免費在線轉換服務;是一款完全免費的在線轉換工具,在線免費完成PDF與word的轉換,在線免費完成圖片與PDF的轉換,在線免費完成PDF與TXT等的轉換,功能齊全,親測有用??!唯一的的缺點就是文檔限制2M。
1.主界面
2.文檔轉換,功能齊全
3.文檔處理
4.在線PS等等
二、office converter
傳送門:https://cn.office-converter.com/Convert-to-Word
這個免費在線轉換器不只是一個在線文檔轉換器, 在線文件轉換器。比如快速轉換 PDF, Docx, Doc, Txt, ODT, SXW, RTF, WPD, HTML file formats轉換成Doc格式. 比如包括PDF轉換成Doc, Docx轉換成Doc,Doc轉換成Doc, Txt轉換成Doc, ODT轉換成Doc, SXW轉換成Doc, RTF轉換成Doc, WPD轉換成Doc, HTML轉換成Doc, PDF轉換成Docx, Docx轉換成Docx, Doc轉換成Docx, Txt轉換成Docx, ODT轉換成Docx, SXW轉換成Docx, RTF轉換成Docx, WPD轉換成Docx, HTML轉換成Docx等.
傳送門:https://www.addpdf.cn/ppt-to-pdf
免費在線完成PDF轉Word,免費在線完成Word轉PDF,免費在線完成PDF轉JPG。功能是少了點,但對文檔大小限制要大點(10M),也挺實用的。
四、LightPDF、smallPDF等等
最重要的一點
有了上面的這些在線PDF轉換Word工具,基本已經能滿足大部分人的需求了。不過,因為這些網站都需要你上傳PDF文檔到它們的服務器之后才能為你轉換,所以如果你的PDF有比較重要且不希望被公開的信息,最好尋求別的途徑進行轉換。或者使用迅捷在線轉換,也就是第一個,這個文檔是有安全性的,自己可以選擇是否公開,也可以直接轉換后去把轉換記錄刪除掉即可。
多時候在工作中會碰到完全由前端導出word文件的需求,因此特地記錄一下比較常用的幾種方式。
該方法提供一個word模板文件,數據通過參數替換的方式傳入word文件中,靈活性較差,適用于簡單的文件導出。需要依賴:docxtemplater、file-saver、jszip-utils、pizzip。
import Docxtemplater from "docxtemplater";
import { saveAs } from "file-saver";
import JSZipUtils from "jszip-utils";
import PizZip from "pizzip";
export function downloadWithTemplate(path, data, fileName) {
JSZipUtils.getBinaryContent(path, (error, content)=> {
if (error) throw error;
const zip=new PizZip(content);
const doc=new Docxtemplater().loadZip(zip);
doc.setData({
...data.form,
// 循環項參數
list: data.list,
outsideList: data.outsideList,
});
try {
doc.render();
} catch (error) {
const e={
message: error.message,
name: error.name,
stack: error.stack,
properties: error.properties,
};
ElMessage.error("文件格式有誤!");
throw error;
}
const out=doc.getZip().generate({
type: "blob",
mimeType:
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
saveAs(out, fileName);
});
}
let data={
form: {
title: "這是word標題",
test: "這是表單1的數據",
test1: "111",
test2: 222,
test3: 333,
},
outsideList: [
{
list: [
{
index: 0,
table: "表格第一項",
table1: "表格第二項",
table2: "表格第三項",
},
{
index: 1,
table: "表格第一項",
table1: "表格第二項",
table2: "表格第三項",
},
],
},
{
list: [
{
index: 0,
table: "表格第一項",
table1: "表格第二項",
table2: "表格第三項",
},
{
index: 1,
table: "表格第一項",
table1: "表格第二項",
table2: "表格第三項",
},
],
},
],
};
downloadWithTemplate("template.docx", data, "模板word.docx")
調用downloadWithTemplate方法即可導出如下文件:
注: 上述方法中的path參數為你在vue項目中存放公共文件的位置,在vue2中為static文件夾下,在vue3中為public文件夾下。
顧名思義,這個方法就是將我們在頁面上書寫的html代碼直接轉換成word文件,這也是我最推薦的一種方法,因為大部分的樣式可控,且畢竟是我們較為熟悉的方式。需要插件: html-docx-js-typescript、file-saver。
import { saveAs } from "file-saver";
import { asBlob } from "html-docx-js-typescript";
export function downloadWordWithHtmlString(html, name) {
let htmlString=`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
${html}
</body>
</html>
`;
asBlob(htmlString).then((data)=> {
saveAs(data, `${name}.docx`);
});
}
`
使用案例:
<div ref="word">
<h3 style="text-align: center">word標題</h3>
<table
border="1"
cellspacing="0"
width="600"
style="font-size: 12px; color: #000; text-align: center"
>
<tr height="50">
<td width="100">1111</td>
<td widt="200" colspan="2">合并單元格</td>
<td width="300">最長的一項</td>
</tr>
<tr height="100">
<td width="100">222</td>
<td width="100">222</td>
<td width="100">222</td>
<td width="100">222</td>
</tr>
</table>
<table width="600" border="1" cellspacing="0">
<tr height="50">
<td width="100">1111</td>
<td rowspan="3">合并包括此行在內的下面三行</td>
</tr>
<tr height="100">
<td>222</td>
</tr>
<tr height="300">
<td>3333</td>
</tr>
<tr>
<td>50</td>
</tr>
</table>
</div>
let word=ref(null);
downloadWordWithHtmlString(word.value.innerHTML, 'html字符串word.docx');
生成的word文件可以看到效果和在網頁中的html代碼一樣:
另外需要注意的是,若是需要在word中添加分頁符,在需要分頁的內容處添加CSS屬性page-break-before即可。此時在瀏覽器上打印出innerHTML值會發現:
mdn上介紹page-break-before屬性已經被break-before屬性替代,但是經過我實際測試發現當html字符串是page-break: always時生成的word文件沒有分頁效果,反而是將其替換回page-break-before后實現了分頁效果。若有大神知道這是什么問題還望不吝賜教。 因此需要在downloadWordWithHtmlString方法中添加一句正則: htmlString=htmlString.replace( /break-(after|before): page/g, "page-break-: always;" );,此時就能實現分頁效果。
第二種方法有個很致命的問題就是它無法在生成的word文件中添加圖片頁眉,我搜遍了npm也只找到一個能添加文字頁眉的插件: html-docx-ts。要想實現這個需求,就需要用到docx插件。 docx官網的介紹是"Easily generate and modify .docx files with JS/TS. Works for Node and on the Browser.",意味著是一個專門用于生成word和修改word的文件。該插件就需要一個一個去配置你要生成的項,然后組合成一個word。一個簡單的案例是:
import {
Document,
Paragraph,
Header,
TextRun,
Table,
TableRow,
TableCell,
WidthType,
Packer,
} from "docx";
import { saveAs } from "file-saver";
const document=new Document({
sections: [
{
headers: {
default: new Header({
children: [new Paragraph("我是頁眉")],
}),
},
children: [
new Paragraph({
children: [
new TextRun({
text: "我是文字內容",
size: 16,
bold: true,
}),
],
}),
new Table({
columnWidths: [1500, 7500],
rows: [
new TableRow({
children: [
new TableCell({
width: {
size: 1500,
type: WidthType.DXA,
},
children: [
new Paragraph({
alignment: "center",
children: [
new TextRun({
text: "測試",
size: 24,
font: {
name: "楷體",
},
}),
],
}),
],
}),
],
}),
],
}),
],
},
],
});
Packer.toBlob(document).then((blob)=> {
saveAs(blob, "test.docx");
});
導出的word文件形式為
下面是我個人總結的比較常見能用到的功能和配置項:
// 導出文字
1.new Paragraph(text) -> 默認字體樣式: 宋體,五號字
2.new Paragraph({
children: [
new TextRun({
text: "我是文字內容",
size: 16, // 對應word中的字體大小8
bold: true, // 是否加粗
underline: {
type: UnderlineType.SINGLE,
color: "#2e32ee",
}, // 下劃線類型及顏色
font: {
name: "仿宋", // 只要是word中有的字體類型都可以生效
},
}),
],
indent: {
left: 100,
}, // 離左邊距離 類似于margin-left
spacing: {
before: 150,
after: 200,
}, // 離上邊和下邊的距離 類似于margin-top/bottom
alignment: "center", // 對齊方式
pageBreakBefore: true, // 是否在這段文字前加入分頁符
})
// 導出表格
new Table({
columnWidths: [1500, 7500], // 表示單行有幾項,總寬度是9000,對應寬度;
rows: [
new TableRow({
children: [
new TableCell({
width: {
size: 1500, // 需與columnWidths的第一項對應
type: WidthType.DXA, // 官網的介紹是Value is in twentieths of a point
// 因為表格的總寬度是以twips(每英寸的1/20)為單位進行計算的
},
children: [
new Paragraph({
alignment: "center",
children: [
new TextRun({
text: "測試",
size: 24,
font: {
name: "楷體",
},
}),
],
}),
],
}),
new TableCell({
width: {
size: 7500,
type: WidthType.DXA,
},
children: [
new Paragraph('ccc'),
],
margins: {
top: 500,
bottom: 500,
left: 500
} // 類似于單元格內容的padding
}),
],
}),
],
})
// 導出圖片
new Paragraph({
children: [
new ImageRun({
data: "base64", // 圖片需轉成base64的形式
transformation: {
width: 100,
height: 30,
}, // 圖片寬高
}),
],
})
// 設置頁眉頁腳
headers: {
default: new Header({
children: [new Paragraph("我是頁眉")],
}),
},
footers: {
default: new Footer({
children: [new Paragraph("我是頁腳")],
}),
}
下面是一個完整的使用案例:
const document=new Document({
sections: [
{
headers: {
default: new Header({
children: [
new Paragraph({
children: [
new ImageRun({
data: "data:image/jpeg;base64,...",
transformation: {
width: 150,
height: 150,
},
}),
],
}),
],
}),
},
footers: {
default: new Footer({
children: [new Paragraph("我是頁腳")],
}),
},
children: [
new Paragraph("第一行直接默認形式"),
new Paragraph({
children: [
new TextRun({
text: "下一頁",
}),
],
pageBreakBefore: true,
}),
new Table({
columnWidths: [1500, 7500],
rows: [
new TableRow({
children: [
new TableCell({
width: {
size: 1500,
type: WidthType.DXA,
},
children: [
new Paragraph({
alignment: "center",
children: [
new TextRun({
text: "測試",
size: 24,
font: {
name: "楷體",
},
}),
],
}),
],
}),
new TableCell({
width: {
size: 7500,
type: WidthType.DXA,
},
children: [
new Paragraph({
children: [
new ImageRun({
data: "data:image/jpeg;base64,...",
transformation: {
width: 150,
height: 150,
},
}),
],
}),
],
margins: {
top: 500,
bottom: 500,
left: 500,
},
}),
],
}),
],
}),
],
},
],
});
Packer.toBlob(document).then((blob)=> {
saveAs(blob, "test.docx");
});
此時導出的word文件如下:
若是以上內容有任何有問題的地方或是更好的解決方案,還望各位大神不吝賜教!
實現文檔在線預覽的方式除了上篇文章 文檔在線預覽新版(一)通過將文件轉成圖片實現在線預覽功能說的將文檔轉成圖片的實現方式外,還有轉成pdf,前端通過pdf.js、pdfobject.js等插件來實現在線預覽,以及本文將要說到的將文檔轉成html的方式來實現在線預覽。
以下代碼分別提供基于aspose、pdfbox、spire來實現來實現txt、word、pdf、ppt、word等文件轉圖片的需求。
Aspose 是一家致力于.Net ,Java,SharePoint,JasperReports和SSRS組件的提供商,數十個國家的數千機構都有用過aspose組件,創建、編輯、轉換或渲染 Office、OpenOffice、PDF、圖像、ZIP、CAD、XPS、EPS、PSD 和更多文件格式。注意aspose是商用組件,未經授權導出文件里面都是是水印(尊重版權,遠離破解版)。
需要在項目的pom文件里添加如下依賴
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>23.1</version>
</dependency>
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-pdf</artifactId>
<version>23.1</version>
</dependency>
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-cells</artifactId>
<version>23.1</version>
</dependency>
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-slides</artifactId>
<version>23.1</version>
</dependency>
因為aspose和spire雖然好用,但是都是是商用組件,所以這里也提供使用開源庫操作的方式的方式。
POI是Apache軟件基金會用Java編寫的免費開源的跨平臺的 Java API,Apache POI提供API給Java程序對Microsoft Office格式檔案讀和寫的功能。
Apache PDFBox是一個開源Java庫,支持PDF文檔的開發和轉換。 使用此庫,您可以開發用于創建,轉換和操作PDF文檔的Java程序。
需要在項目的pom文件里添加如下依賴
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-excelant</artifactId>
<version>5.2.0</version>
</dependency>
spire一款專業的Office編程組件,涵蓋了對Word、Excel、PPT、PDF等文件的讀寫、編輯、查看功能。spire提供免費版本,但是存在只能導出前3頁以及只能導出前500行的限制,只要達到其一就會觸發限制。需要超出前3頁以及只能導出前500行的限制的這需要購買付費版(尊重版權,遠離破解版)。這里使用免費版進行演示。
spire在添加pom之前還得先添加maven倉庫來源
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
接著在項目的pom文件里添加如下依賴
免費版:
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.office.free</artifactId>
<version>5.3.1</version>
</dependency>
付費版版:
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.office</artifactId>
<version>5.3.1</version>
</dependency>
public static String wordToHtmlStr(String wordPath) {
try {
Document doc=new Document(wordPath); // Address是將要被轉化的word文檔
String htmlStr=doc.toString();
return htmlStr;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
驗證結果:
public String wordToHtmlStr(String wordPath) throws TransformerException, IOException, ParserConfigurationException {
String htmlStr=null;
String ext=wordPath.substring(wordPath.lastIndexOf("."));
if (ext.equals(".docx")) {
htmlStr=word2007ToHtmlStr(wordPath);
} else if (ext.equals(".doc")){
htmlStr=word2003ToHtmlStr(wordPath);
} else {
throw new RuntimeException("文件格式不正確");
}
return htmlStr;
}
public String word2007ToHtmlStr(String wordPath) throws IOException {
// 使用內存輸出流
try(ByteArrayOutputStream out=new ByteArrayOutputStream()){
word2007ToHtmlOutputStream(wordPath, out);
return out.toString();
}
}
private void word2007ToHtmlOutputStream(String wordPath,OutputStream out) throws IOException {
ZipSecureFile.setMinInflateRatio(-1.0d);
InputStream in=Files.newInputStream(Paths.get(wordPath));
XWPFDocument document=new XWPFDocument(in);
XHTMLOptions options=XHTMLOptions.create().setIgnoreStylesIfUnused(false).setImageManager(new Base64EmbedImgManager());
// 使用內存輸出流
XHTMLConverter.getInstance().convert(document, out, options);
}
private String word2003ToHtmlStr(String wordPath) throws TransformerException, IOException, ParserConfigurationException {
org.w3c.dom.Document htmlDocument=word2003ToHtmlDocument(wordPath);
// Transform document to string
StringWriter writer=new StringWriter();
TransformerFactory tf=TransformerFactory.newInstance();
Transformer transformer=tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "html");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.transform(new DOMSource(htmlDocument), new StreamResult(writer));
return writer.toString();
}
private org.w3c.dom.Document word2003ToHtmlDocument(String wordPath) throws IOException, ParserConfigurationException {
InputStream input=Files.newInputStream(Paths.get(wordPath));
HWPFDocument wordDocument=new HWPFDocument(input);
WordToHtmlConverter wordToHtmlConverter=new WordToHtmlConverter(
DocumentBuilderFactory.newInstance().newDocumentBuilder()
.newDocument());
wordToHtmlConverter.setPicturesManager((content, pictureType, suggestedName, widthInches, heightInches) -> {
System.out.println(pictureType);
if (PictureType.UNKNOWN.equals(pictureType)) {
return null;
}
BufferedImage bufferedImage=ImgUtil.toImage(content);
String base64Img=ImgUtil.toBase64(bufferedImage, pictureType.getExtension());
// 帶圖片的word,則將圖片轉為base64編碼,保存在一個頁面中
StringBuilder sb=(new StringBuilder(base64Img.length() + "data:;base64,".length()).append("data:;base64,").append(base64Img));
return sb.toString();
});
// 解析word文檔
wordToHtmlConverter.processDocument(wordDocument);
return wordToHtmlConverter.getDocument();
}
public String wordToHtmlStr(String wordPath) throws IOException {
try(ByteArrayOutputStream outputStream=new ByteArrayOutputStream()) {
Document document=new Document();
document.loadFromFile(wordPath);
document.saveToFile(outputStream, FileFormat.Html);
return outputStream.toString();
}
}
public static String pdfToHtmlStr(String pdfPath) throws IOException, ParserConfigurationException {
PDDocument document=PDDocument.load(new File(pdfPath));
Writer writer=new StringWriter();
new PDFDomTree().writeText(document, writer);
writer.close();
document.close();
return writer.toString();
}
驗證結果:
public String pdfToHtmlStr(String pdfPath) throws IOException, ParserConfigurationException {
PDDocument document=PDDocument.load(new File(pdfPath));
Writer writer=new StringWriter();
new PDFDomTree().writeText(document, writer);
writer.close();
document.close();
return writer.toString();
}
public String pdfToHtmlStr(String pdfPath) throws IOException, ParserConfigurationException {
try(ByteArrayOutputStream outputStream=new ByteArrayOutputStream()) {
PdfDocument pdf=new PdfDocument();
pdf.loadFromFile(pdfPath);
return outputStream.toString();
}
}
public static String excelToHtmlStr(String excelPath) throws Exception {
FileInputStream fileInputStream=new FileInputStream(excelPath);
Workbook workbook=new XSSFWorkbook(fileInputStream);
DataFormatter dataFormatter=new DataFormatter();
FormulaEvaluator formulaEvaluator=workbook.getCreationHelper().createFormulaEvaluator();
Sheet sheet=workbook.getSheetAt(0);
StringBuilder htmlStringBuilder=new StringBuilder();
htmlStringBuilder.append("<html><head><title>Excel to HTML using Java and POI library</title>");
htmlStringBuilder.append("<style>table, th, td { border: 1px solid black; }</style>");
htmlStringBuilder.append("</head><body><table>");
for (Row row : sheet) {
htmlStringBuilder.append("<tr>");
for (Cell cell : row) {
CellType cellType=cell.getCellType();
if (cellType==CellType.FORMULA) {
formulaEvaluator.evaluateFormulaCell(cell);
cellType=cell.getCachedFormulaResultType();
}
String cellValue=dataFormatter.formatCellValue(cell, formulaEvaluator);
htmlStringBuilder.append("<td>").append(cellValue).append("</td>");
}
htmlStringBuilder.append("</tr>");
}
htmlStringBuilder.append("</table></body></html>");
return htmlStringBuilder.toString();
}
返回的html字符串:
<html><head><title>Excel to HTML using Java and POI library</title><style>table, th, td { border: 1px solid black; }</style></head><body><table><tr><td>序號</td><td>姓名</td><td>性別</td><td>聯系方式</td><td>地址</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr></table></body></html>
public String excelToHtmlStr(String excelPath) throws Exception {
FileInputStream fileInputStream=new FileInputStream(excelPath);
try (Workbook workbook=WorkbookFactory.create(new File(excelPath))){
DataFormatter dataFormatter=new DataFormatter();
FormulaEvaluator formulaEvaluator=workbook.getCreationHelper().createFormulaEvaluator();
org.apache.poi.ss.usermodel.Sheet sheet=workbook.getSheetAt(0);
StringBuilder htmlStringBuilder=new StringBuilder();
htmlStringBuilder.append("<html><head><title>Excel to HTML using Java and POI library</title>");
htmlStringBuilder.append("<style>table, th, td { border: 1px solid black; }</style>");
htmlStringBuilder.append("</head><body><table>");
for (Row row : sheet) {
htmlStringBuilder.append("<tr>");
for (Cell cell : row) {
CellType cellType=cell.getCellType();
if (cellType==CellType.FORMULA) {
formulaEvaluator.evaluateFormulaCell(cell);
cellType=cell.getCachedFormulaResultType();
}
String cellValue=dataFormatter.formatCellValue(cell, formulaEvaluator);
htmlStringBuilder.append("<td>").append(cellValue).append("</td>");
}
htmlStringBuilder.append("</tr>");
}
htmlStringBuilder.append("</table></body></html>");
return htmlStringBuilder.toString();
}
}
public String excelToHtmlStr(String excelPath) throws Exception {
try(ByteArrayOutputStream outputStream=new ByteArrayOutputStream()) {
Workbook workbook=new Workbook();
workbook.loadFromFile(excelPath);
workbook.saveToStream(outputStream, com.spire.xls.FileFormat.HTML);
return outputStream.toString();
}
}
有時我們是需要的不僅僅返回html字符串,而是需要生成一個html文件這時應該怎么做呢?一個改動量小的做法就是使用org.apache.commons.io包下的FileUtils工具類寫入目標地址:
首先需要引入pom:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
相關代碼:
String htmlStr=FileConvertUtil.pdfToHtmlStr("D:\\書籍\\電子書\\小說\\歷史小說\\最后的可汗.doc");
FileUtils.write(new File("D:\\test\\doc.html"), htmlStr, "utf-8");
除此之外,還可以對上面的代碼進行一些調整,已實現生成html文件,代碼調整如下:
word原文件效果:
public static void wordToHtml(String wordPath, String htmlPath) {
try {
File sourceFile=new File(wordPath);
String path=htmlPath + File.separator + sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf(".")) + ".html";
File file=new File(path); // 新建一個空白pdf文檔
FileOutputStream os=new FileOutputStream(file);
Document doc=new Document(wordPath); // Address是將要被轉化的word文檔
HtmlSaveOptions options=new HtmlSaveOptions();
options.setExportImagesAsBase64(true);
options.setExportRelativeFontSize(true);
doc.save(os, options);
} catch (Exception e) {
e.printStackTrace();
}
}
轉換成html的效果:
public void wordToHtml(String wordPath, String htmlPath) throws TransformerException, IOException, ParserConfigurationException {
htmlPath=FileUtil.getNewFileFullPath(wordPath, htmlPath, "html");
String ext=wordPath.substring(wordPath.lastIndexOf("."));
if (ext.equals(".docx")) {
word2007ToHtml(wordPath, htmlPath);
} else if (ext.equals(".doc")){
word2003ToHtml(wordPath, htmlPath);
} else {
throw new RuntimeException("文件格式不正確");
}
}
public void word2007ToHtml(String wordPath, String htmlPath) throws TransformerException, IOException, ParserConfigurationException {
//try(OutputStream out=Files.newOutputStream(Paths.get(path))){
try(FileOutputStream out=new FileOutputStream(htmlPath)){
word2007ToHtmlOutputStream(wordPath, out);
}
}
private void word2007ToHtmlOutputStream(String wordPath,OutputStream out) throws IOException {
ZipSecureFile.setMinInflateRatio(-1.0d);
InputStream in=Files.newInputStream(Paths.get(wordPath));
XWPFDocument document=new XWPFDocument(in);
XHTMLOptions options=XHTMLOptions.create().setIgnoreStylesIfUnused(false).setImageManager(new Base64EmbedImgManager());
// 使用內存輸出流
XHTMLConverter.getInstance().convert(document, out, options);
}
public void word2003ToHtml(String wordPath, String htmlPath) throws TransformerException, IOException, ParserConfigurationException {
org.w3c.dom.Document htmlDocument=word2003ToHtmlDocument(wordPath);
// 生成html文件地址
try(OutputStream outStream=Files.newOutputStream(Paths.get(htmlPath))){
DOMSource domSource=new DOMSource(htmlDocument);
StreamResult streamResult=new StreamResult(outStream);
TransformerFactory factory=TransformerFactory.newInstance();
Transformer serializer=factory.newTransformer();
serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
serializer.setOutputProperty(OutputKeys.METHOD, "html");
serializer.transform(domSource, streamResult);
}
}
private org.w3c.dom.Document word2003ToHtmlDocument(String wordPath) throws IOException, ParserConfigurationException {
InputStream input=Files.newInputStream(Paths.get(wordPath));
HWPFDocument wordDocument=new HWPFDocument(input);
WordToHtmlConverter wordToHtmlConverter=new WordToHtmlConverter(
DocumentBuilderFactory.newInstance().newDocumentBuilder()
.newDocument());
wordToHtmlConverter.setPicturesManager((content, pictureType, suggestedName, widthInches, heightInches) -> {
System.out.println(pictureType);
if (PictureType.UNKNOWN.equals(pictureType)) {
return null;
}
BufferedImage bufferedImage=ImgUtil.toImage(content);
String base64Img=ImgUtil.toBase64(bufferedImage, pictureType.getExtension());
// 帶圖片的word,則將圖片轉為base64編碼,保存在一個頁面中
StringBuilder sb=(new StringBuilder(base64Img.length() + "data:;base64,".length()).append("data:;base64,").append(base64Img));
return sb.toString();
});
// 解析word文檔
wordToHtmlConverter.processDocument(wordDocument);
return wordToHtmlConverter.getDocument();
}
轉換成html的效果:
public void wordToHtml(String wordPath, String htmlPath) {
htmlPath=FileUtil.getNewFileFullPath(wordPath, htmlPath, "html");
Document document=new Document();
document.loadFromFile(wordPath);
document.saveToFile(htmlPath, FileFormat.Html);
}
轉換成html的效果:
因為使用的是免費版,存在頁數和字數限制,需要完整功能的的可以選擇付費版本。PS:這回76頁的文檔居然轉成功了前50頁。
圖片版pdf原文件效果:
文字版pdf原文件效果:
public static void pdfToHtml(String pdfPath, String htmlPath) throws IOException, ParserConfigurationException {
File file=new File(pdfPath);
String path=htmlPath + File.separator + file.getName().substring(0, file.getName().lastIndexOf(".")) + ".html";
PDDocument document=PDDocument.load(new File(pdfPath));
Writer writer=new PrintWriter(path, "UTF-8");
new PDFDomTree().writeText(document, writer);
writer.close();
document.close();
}
圖片版PDF文件驗證結果:
文字版PDF文件驗證結果:
public void pdfToHtml(String pdfPath, String htmlPath) throws IOException, ParserConfigurationException {
String path=FileUtil.getNewFileFullPath(pdfPath, htmlPath, "html");
PDDocument document=PDDocument.load(new File(pdfPath));
Writer writer=new PrintWriter(path, "UTF-8");
new PDFDomTree().writeText(document, writer);
writer.close();
document.close();
}
圖片版PDF文件驗證結果:
文字版PDF原文件效果:
public void pdfToHtml(String pdfPath, String htmlPath) throws IOException, ParserConfigurationException {
htmlPath=FileUtil.getNewFileFullPath(pdfPath, htmlPath, "html");
PdfDocument pdf=new PdfDocument();
pdf.loadFromFile(pdfPath);
pdf.saveToFile(htmlPath, com.spire.pdf.FileFormat.HTML);
}
圖片版PDF文件驗證結果:
因為使用的是免費版,所以只有前三頁是正常的。。。有超過三頁需求的可以選擇付費版本。
文字版PDF原文件效果:
報錯了無法轉換。。。
java.lang.NullPointerException
at com.spire.pdf.PdfPageWidget.spr┢?(Unknown Source)
at com.spire.pdf.PdfPageWidget.getSize(Unknown Source)
at com.spire.pdf.PdfPageBase.spr???—(Unknown Source)
at com.spire.pdf.PdfPageBase.getActualSize(Unknown Source)
at com.spire.pdf.PdfPageBase.getSection(Unknown Source)
at com.spire.pdf.general.PdfDestination.spr︻┎?—(Unknown Source)
at com.spire.pdf.general.PdfDestination.spr┻┑?—(Unknown Source)
at com.spire.pdf.general.PdfDestination.getElement(Unknown Source)
at com.spire.pdf.primitives.PdfDictionary.setProperty(Unknown Source)
at com.spire.pdf.bookmarks.PdfBookmark.setDestination(Unknown Source)
at com.spire.pdf.bookmarks.PdfBookmarkWidget.spr┭┘?—(Unknown Source)
at com.spire.pdf.bookmarks.PdfBookmarkWidget.getDestination(Unknown Source)
at com.spire.pdf.PdfDocumentBase.spr??(Unknown Source)
at com.spire.pdf.widget.PdfPageCollection.spr┦?(Unknown Source)
at com.spire.pdf.widget.PdfPageCollection.removeAt(Unknown Source)
at com.spire.pdf.PdfDocumentBase.spr┞?(Unknown Source)
at com.spire.pdf.PdfDocument.loadFromFile(Unknown Source)
excel原文件效果:
public void excelToHtml(String excelPath, String htmlPath) throws Exception {
htmlPath=FileUtil.getNewFileFullPath(excelPath, htmlPath, "html");
Workbook workbook=new Workbook(excelPath);
com.aspose.cells.HtmlSaveOptions options=new com.aspose.cells.HtmlSaveOptions();
workbook.save(htmlPath, options);
}
轉換成html的效果:
public void excelToHtml(String excelPath, String htmlPath) throws Exception {
String path=FileUtil.getNewFileFullPath(excelPath, htmlPath, "html");
try(FileOutputStream fileOutputStream=new FileOutputStream(path)){
String htmlStr=excelToHtmlStr(excelPath);
byte[] bytes=htmlStr.getBytes();
fileOutputStream.write(bytes);
}
}
public String excelToHtmlStr(String excelPath) throws Exception {
FileInputStream fileInputStream=new FileInputStream(excelPath);
try (Workbook workbook=WorkbookFactory.create(new File(excelPath))){
DataFormatter dataFormatter=new DataFormatter();
FormulaEvaluator formulaEvaluator=workbook.getCreationHelper().createFormulaEvaluator();
org.apache.poi.ss.usermodel.Sheet sheet=workbook.getSheetAt(0);
StringBuilder htmlStringBuilder=new StringBuilder();
htmlStringBuilder.append("<html><head><title>Excel to HTML using Java and POI library</title>");
htmlStringBuilder.append("<style>table, th, td { border: 1px solid black; }</style>");
htmlStringBuilder.append("</head><body><table>");
for (Row row : sheet) {
htmlStringBuilder.append("<tr>");
for (Cell cell : row) {
CellType cellType=cell.getCellType();
if (cellType==CellType.FORMULA) {
formulaEvaluator.evaluateFormulaCell(cell);
cellType=cell.getCachedFormulaResultType();
}
String cellValue=dataFormatter.formatCellValue(cell, formulaEvaluator);
htmlStringBuilder.append("<td>").append(cellValue).append("</td>");
}
htmlStringBuilder.append("</tr>");
}
htmlStringBuilder.append("</table></body></html>");
return htmlStringBuilder.toString();
}
}
轉換成html的效果:
public void excelToHtml(String excelPath, String htmlPath) throws Exception {
htmlPath=FileUtil.getNewFileFullPath(excelPath, htmlPath, "html");
Workbook workbook=new Workbook();
workbook.loadFromFile(excelPath);
workbook.saveToFile(htmlPath, com.spire.xls.FileFormat.HTML);
}
轉換成html的效果:
從上述的效果展示我們可以發現其實轉成html效果不是太理想,很多細節樣式沒有還原,這其實是因為這類轉換往往都是追求目標是通過使用文檔中的語義信息并忽略其他細節來生成簡單干凈的 HTML,所以在轉換過程中復雜樣式被忽略,比如居中、首行縮進、字體,文本大小,顏色。舉個例子在轉換是 會將應用標題 1 樣式的任何段落轉換為 h1 元素,而不是嘗試完全復制標題的樣式。所以轉成html的顯示效果往往和原文檔不太一樣。這意味著對于較復雜的文檔而言,這種轉換不太可能是完美的。但如果都是只使用簡單樣式文檔或者對文檔樣式不太關心的這種方式也不妨一試。
PS:如果想要展示效果好的話,其實可以將上篇文章《文檔在線預覽(一)通過將txt、word、pdf轉成圖片實現在線預覽功能》說的內容和本文結合起來使用,即將文檔里的內容都生成成圖片(很可能是多張圖片),然后將生成的圖片全都放到一個html頁面里 ,用html+css來保持樣式并實現多張圖片展示,再將html返回。開源組件kkfilevie就是用的就是這種做法。
kkfileview展示效果如下:
下圖是kkfileview返回的html代碼,從html代碼我們可以看到kkfileview其實是將文件(txt文件除外)每頁的內容都轉成了圖片,然后將這些圖片都嵌入到一個html里,再返回給用戶一個html頁面。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。