狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

【JAVA】iTEXT將html文檔轉PDF,spire.doc包html轉word(包括樣式修改和添加圖片/頁碼等設置)

admin
2023年5月15日 12:5 本文熱度 2067

項目需求

使用velocity模板生成html內容,將含有標題 / 段落 / 表格 / 圖片 的html文件轉化成PDF和word格式,并保留良好樣式。

iText

起初只想實現word功能,但經過嘗試和查詢一些例如poi等工具,都無法較好的保留原有的復雜樣式,后更換pdf需求進行嘗試,itext生成pdf已經非常完美了。
生成word樣式沒有嘗試,感覺比較麻煩。
后來采用spire的free包將pdf轉word樣式保持很好,但是項目環境中遇到問題,轉戰html轉word。
注意:不要將spire的pdf和word包同時引用,如果需要可以直接使用office包,會產生一些例如注冊許可方面的沖突。

spire.pdf / spire.doc / spire.office

很好的第三方工具,能完美實現html轉pdf和word等格式文件,最關鍵的是有free版本,雖然有10頁的限制,結合需求頁可能夠用和付費版功能上無差別。
付費版本也一樣可以用,只是會在左上角有紅色警告信息,其實word可以手動刪除,pdf可以通過添加圖片的方式遮蓋掉。
注意:我們的項目環境是Linux / jdk1.7 / weblogic12.1.3.0.0(pdf轉word–使用doc包就會報錯UnkownSource【原因不明】,最好直接html轉word最終解決問題),html轉word表頭的css樣式可能會無法解析,使用基本樣式就好。

spire.pdf / spire.doc 冰藍科技 中文文檔

html轉pdf

引入jar包

引入itext倉庫
        <repository>
        <id>itext</id>
        <name>iText Repository - releases</name>
        <url>https://repo.itextsupport.com/releases</url>
        </repository>
在pom.xml引入maven(不包括spire.pdf)
         <!-- itextpdf -->
         <dependency>
         <groupId>com.lowagie</groupId>
         <artifactId>itext</artifactId>
         <version>2.1.7</version>
         </dependency>
         <dependency>
         <groupId>com.lowagie</groupId>
         <artifactId>itext-rtf</artifactId>
         <version>2.1.7</version>
         </dependency>
         <dependency>
         <groupId>com.itextpdf</groupId>
         <artifactId>itext-asian</artifactId>
         <version>5.2.0</version>
         </dependency>
         <dependency>
         <groupId>com.itextpdf</groupId>
         <artifactId>itextpdf</artifactId>
         <version>5.5.10</version>
         </dependency>
         <!-- pdfHTML -->
         <dependency>
         <groupId>com.itextpdf</groupId>
         <artifactId>itext7-core</artifactId>
         <version>7.1.0</version>
         <type>pom</type>
         <exclusions><exclusion>
         <artifactId>slf4j-api</artifactId>
         <groupId>org.slf4j</groupId>
         </exclusion>
         </exclusions>
         </dependency>
         <dependency>
         <groupId>com.itextpdf</groupId>
         <artifactId>html2pdf</artifactId>
         <version>2.0.0</version>
         </dependency>
         <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-io</artifactId>
         <version>1.3.2</version>
         </dependency>
         <dependency>
         <groupId>org.xhtmlrenderer</groupId>
         <artifactId>flying-saucer-pdf</artifactId>
         <version>9.0.8</version>
         </dependency>
         </dependencies>
可以下載spire.pdf.free以及各種實用jar包的maven倉庫

maven倉庫(內含spire.pdf.free和spire.doc.free)

生成pdf

package com.sy.util;import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.attach.impl.DefaultTagWorkerFactory;
import com.itextpdf.html2pdf.css.media.MediaDeviceDescription;
import com.itextpdf.html2pdf.css.media.MediaType;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.layout.font.FontProvider;
import org.apache.commons.io.FileUtils;
import org.apache.poi.util.IOUtils;
import java.io.*;
import static com.itextpdf.kernel.geom.PageSize.A4;
import static com.itextpdf.kernel.geom.PageSize.A3;public class PdfService {
//private static final Logger LOGGER = LoggerFactory.getLogger(PdffromHTML.class);
public static final String FONT_NAME = "simsun.ttf";
public void copyFont(String targetDir,String fontPath) {
FileOutputStream fout = null;
FileInputStream fileInputStream = null;
try {
//InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(FONT_CLASS_PATH);
fileInputStream = new FileInputStream(fontPath+"/WEB-INF/fonts/simsun.ttf");
File dir = new File(targetDir);FileUtils.forceMkdir(dir);fout = new FileOutputStream(targetDir + "simsun.ttf");
if (fileInputStream != null && fout != null) {
org.apache.commons.io.IOUtils.copy(fileInputStream, fout);
}
} 
catch (Exception e) 
{
//LOGGER.error("failed to copy font: ", e);
e.printStackTrace();
}
finally 
{
 if(null!=fileInputStream){
 try {fileInputStream.close();
} 
catch (IOException e) 
{
 e.printStackTrace();
}
}
if(null!=fout){
try 
{
fout.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
 public void createPdffromHtml(String pdfFileName, InputStream htmlInputStream, String resourcePrefix)
 {
 PdfDocument pdfDoc = null;
 FileOutputStream outputStream = null;
 PdfWriter pdfWriter = null;
 try {
 outputStream = new FileOutputStream(resourcePrefix + pdfFileName);
 WriterProperties writerProperties = new WriterProperties();
 writerProperties.addXmpMetadata();
 pdfWriter = new PdfWriter(outputStream, writerProperties);
 pdfDoc = createPdfDoc(pdfWriter);
 PdfDocument pdfDocument = new PdfDocument(pdfWriter);
 pdfDocument.setDefaultPageSize(A3);
 //轉換器
 ConverterProperties props = createConverterProperties(resourcePrefix);
 props.setBaseUri(resourcePrefix);
 //設置媒體的描述方式
 MediaDeviceDescription mediaDeviceDescription = new MediaDeviceDescription(MediaType.SCREEN);
 props.setMediaDeviceDescription(mediaDeviceDescription);
 HtmlConverter.convertToPdf(htmlInputStream,pdfDocument, props);
 pdfDocument.close();
 }
  catch (Exception e) 
 {
 //LOGGER.error("failed to create pdf from html exception: ", e);
 e.printStackTrace();
 }
  finally 
 {
 try 
 {
 outputStream.close();
 pdfWriter.close();
 } 
 catch (IOException e) 
 {
 e.printStackTrace();
 }
 finally 
 {
 outputStream = null;
 pdfWriter = null;
 }
 IOUtils.closeQuietly(pdfDoc);
 }
 }
 
    private PdfDocument createPdfDoc(PdfWriter pdfWriter) 
    {
         PdfDocument pdfDoc;
         pdfDoc = new PdfDocument(pdfWriter);
         pdfDoc.getCatalog().setLang(new PdfString("zh-CN"));
         pdfDoc.setTagged();
         pdfDoc.getCatalog().setViewerPreferences(new PdfViewerPreferences().setDisplayDocTitle(true));
         return pdfDoc;
    }
 
    private ConverterProperties createConverterProperties(String resourcePrefix) 
    {
        ConverterProperties props = new ConverterProperties();
        props.setFontProvider(createFontProvider(resourcePrefix));
        props.setBaseUri(resourcePrefix);
        props.setCharset("UTF-8");
        DefaultTagWorkerFactory tagWorkerFactory = new DefaultTagWorkerFactory();
        props.setTagWorkerFactory(tagWorkerFactory);
        return props;
    }
 
    private FontProvider createFontProvider(String resourcePrefix)
    {
        FontProvider fp = new FontProvider();
        fp.addStandardPdfFonts();
        fp.addDirectory(resourcePrefix);return fp;
    }
}
下面為main方法
 //pdf文件加載和生成統一路徑String pdfPath = localFilePath + name + ".pdf";File temFile = new File(localFilePath);if (!temFile.exists()) {temFile.mkdirs();}// 添加字體,這一步很關鍵,否則中文會顯示不出來PdfService pdfService = new PdfService();File file = new File(localFilePath + PdfService.FONT_NAME);if (!file.exists()) {//加載字體庫pdfService.copyFont(localFilePath,realPath);}//---------------------FileInputStream inputStream = new FileInputStream(url);File pdfFile = new File(pdfPath);//TODO html To PDFpdfService.createPdffromHtml(pdfFile.getName(), inputStream, localFilePath);

pdf布局設置(以下內容通過spire.doc/pdf包處理)

package com.sy.util;import com.spire.doc.FileFormat;
import com.spire.doc.documents.*;
import com.spire.doc.fields.DocPicture;
import com.spire.doc.fields.TextRange;
import com.spire.pdf.*;
import com.spire.doc.*;
import com.spire.pdf.annotations.PdfRubberStampAnnotation;
import com.spire.pdf.annotations.appearance.PdfAppearance;
import com.spire.pdf.automaticfields.PdfCompositeField;
import com.spire.pdf.automaticfields.PdfPageCountField;
import com.spire.pdf.automaticfields.PdfPageNumberField;
import com.spire.pdf.graphics.*;
import java.awt.*;
import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import com.spire.doc.FileFormat.*;public class PdfPageSetting 
{
public static final int FLAG = 2;
public void pdfPageSetting(String url,int flag)
{
//創建PdfDocument對象
PdfDocument originalDoc = new PdfDocument();
//加載PDF文件
originalDoc.loadfromFile(url);
//第一頁插入空白頁(目的是刪除spirefree的內置紅色警告語,主要是為了生成word使用,pdf可以用添加圖片方法進行遮蓋)
originalDoc.getPages().insert(0);
//創建一個新的PdfDocument實例
PdfDocument newDoc = new PdfDocument();
//遍歷所有PDF 頁面
Dimension2D dimension2D = new Dimension();
for (int i = 0; i < originalDoc.getPages().getCount(); i++) 
{
PdfPageBase page = originalDoc.getPages().get(i);
if (flag==1)
{
//設置新文檔頁面寬、高為原來的1倍
float scale = 1.0f;
float width = (float) page.getSize().getWidth() * scale;
float height = (float) page.getSize().getHeight() * scale;
dimension2D.setSize(width, height);
//設置新文檔第一頁的頁邊距為左右
PdfMargins margins = new PdfMargins(0, 20);
PdfPageBase newPage = newDoc.getPages().add(dimension2D, margins);
//復制原文檔的內容到新文檔
newPage.getCanvas().drawTemplate(page.createTemplate(), new Point2D.Float());
}
if (flag==2)
{
//設置新文檔頁邊距為左右0、上下20(不能隨意更改,會影響主標題位置)
PdfMargins margins = new PdfMargins(0,20,0,0);
//設置新文檔頁面大小為A3
PdfPageBase newPage = newDoc.getPages().add(PdfPageSize.A3, margins);
//調整畫布,設置內容也根據頁面的大小進行縮放
double wScale = (PdfPageSize.A3.getWidth() - 10) / PdfPageSize.A3.getWidth();
double hScale = (PdfPageSize.A3.getHeight() - 10) / PdfPageSize.A3.getHeight();
newPage.getCanvas().translateTransform(wScale, hScale);
//復制原文檔的內容到新文檔
newPage.getCanvas().drawTemplate(page.createTemplate(), new Point2D.Float());
}
if (flag==3)
{
//設置新文檔頁邊距
PdfMargins margins = new PdfMargins(0, 0);
//設置新文檔頁面大小為A3, 頁面旋轉角度為0,紙張方向為水平
PdfPageBase newPage = newDoc.getPages().add(PdfPageSize.A4, margins, PdfPageRotateAngle.Rotate_Angle_0, PdfPageOrientation.Landscape);
//調整畫布,設置內容也根據頁面的大小進行縮放
double wScale = PdfPageSize.A4.getHeight() / page.getSize().getWidth();
double hScale = PdfPageSize.A4.getWidth() / page.getSize().getHeight();
newPage.getCanvas().translateTransform(wScale, hScale);
//復制原文檔的內容到新文檔
newPage.getCanvas().drawTemplate(page.createTemplate(), new Point2D.Float());
}
}
//保存
PDFnewDoc.saveToFile(url);
newDoc.close();
originalDoc.close();
}

pdf添加頁碼

  /*** 添加頁碼* @param targetPath*/public void addPageNum(String targetPath) {//加載PDF文檔PdfDocument doc = new PdfDocument();doc.loadfromFile(targetPath);//刪除第一頁空白頁doc.getPages().removeAt(0);//創建字體PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Default", Font.PLAIN, 10),true);//獲取頁面尺寸Dimension2D pageSize = doc.getPages().get(0).getSize();//初始化y坐標float y = (float) pageSize.getHeight() - 20;//遍歷文檔中的頁for (int i = 0; i < doc.getPages().getCount(); i++) {//初始化頁碼域PdfPageNumberField number = new PdfPageNumberField();//初始化總頁數域//PdfPageCountField count = new PdfPageCountField();//創建復合域PdfCompositeField compositeField = new PdfCompositeField(font, PdfBrushes.getBlack(),"{0}", number);//設置復合域內文字對齊方式compositeField.setStringFormat(new PdfStringFormat(PdfTextAlignment.Right, PdfVerticalAlignment.Top));//測量文字大小Dimension2D textSize = font.measureString(compositeField.getText());//設置復合域的在PDF頁面上的位置及大小compositeField.setBounds(new Rectangle2D.Float(((float) pageSize.getWidth() - (float) textSize.getWidth())/2, y, (float) textSize.getWidth(), (float) textSize.getHeight()));//將復合域添加到PDF頁面compositeField.draw(doc.getPages().get(i).getCanvas());}//保存為另外一個文檔doc.saveToFile(targetPath);doc.close();}

pdf添加圖片

   /*** 添加圖片到PDF* @param url  pdf文件* @param baseUrl  項目路徑* @param savePath  文件保存路徑*/public static void addImgToPdf(String url,String baseUrl) {//創建PdfDocument對象PdfDocument doc = new PdfDocument();//加載PDF文檔doc.loadfromFile(url);//刪除第一頁空白頁//doc.getPages().removeAt(0);for (int i = 0; i < doc.getPages().getCount(); i++) {//獲取第i頁PdfPageBase page = doc.getPages().get(i);//加載圖片到PdfImage對象PdfImage image = PdfImage.fromFile(baseUrl + "img\\custom\\pdf.png");//獲取圖片高寬int width = image.getWidth();int height = image.getHeight();//創建PdfTemplate對象,大小跟圖片一致PdfTemplate template = new PdfTemplate(width, height);//在模板上繪制圖片template.getGraphics().drawImage(image, 0, 0, width, height);//創建PdfRubebrStampAnnotation對象,指定大小和位置Rectangle2D rect = new Rectangle2D.Float((float)(0), (float)(0), 835, 50);PdfRubberStampAnnotation stamp = new PdfRubberStampAnnotation(rect);//創建PdfAppearance對象PdfAppearance pdfAppearance = new PdfAppearance(stamp);//將模板應用為PdfAppearance的一般狀態pdfAppearance.setNormal(template);//將PdfAppearance 應用為圖章的樣式stamp.setAppearance(pdfAppearance);//添加圖章到PDFpage.getAnnotationsWidget().add(stamp);}//保存文檔doc.saveToFile(url);doc.close();}

pdf轉word(windows/linux和tomcat下測試可用)

 		//創建PdfDocument對象PdfDocument doc = new PdfDocument();//加載PDF文檔doc.loadfromFile(url);//保存文檔doc.saveToFile(url);

html轉word

		//TODO html To DOCXDocument word = new Document();//html文件地址word.loadfromFile(url);word.saveToFile(wordPath, FileFormat.Docx);word.close();//TODO 添加頁眉和頁腳,設置word頁邊距(realPath為頁眉圖片地址)setUpPageOfWord(wordPath,realPath);

word添加頁眉頁腳和頁碼

  /*** word添加頁眉* @param url* @param baseUrl* @param*/public static void setUpPageOfWord(String url,String baseUrl) {//創建Document對象Document doc = new Document();doc.loadfromFile(url);//獲取第一頁Section section = doc.getSections().get(0);Dimension2D dimension2D = new Dimension();dimension2D.setSize(800,1200);section.getPageSetup().setPageSize(dimension2D);//設置頁邊距section.getPageSetup().getMargins().setTop(40f);section.getPageSetup().getMargins().setBottom(40f);section.getPageSetup().getMargins().setLeft(60f);section.getPageSetup().getMargins().setRight(60f);//調用insertHeaderAndFooter方法插入頁眉頁腳到第一個sectioninsertHeaderAndFooter(section,baseUrl);//保存doc.saveToFile(url);doc.close();}private static void insertHeaderAndFooter(Section section,String baseUrl) {//分別獲取section的頁眉頁腳HeaderFooter header = section.getHeadersFooters().getHeader();HeaderFooter footer = section.getHeadersFooters().getFooter();//添加段落到頁眉Paragraph headerParagraph = header.addParagraph();//插入圖片到頁眉的段落DocPicture headerPicture = headerParagraph.appendPicture(baseUrl + "img/custom/word.png");headerPicture.setHorizontalAlignment(ShapeHorizontalAlignment.Left);headerPicture.setVerticalOrigin(VerticalOrigin.Top_Margin_Area);headerPicture.setVerticalAlignment(ShapeVerticalAlignment.Bottom);//添加文字到頁眉的段落TextRange text = headerParagraph.appendText("上海煙草集團");//text.getCharacterFormat().setFontName("default");text.getCharacterFormat().setFontSize(10);text.getCharacterFormat().setItalic(true);headerParagraph.getFormat().setHorizontalAlignment(HorizontalAlignment.Right);//設置文字環繞方式headerPicture.setTextWrappingStyle(TextWrappingStyle.Behind);//設置頁眉段落的底部邊線樣式headerParagraph.getFormat().getBorders().getBottom().setBorderType(BorderStyle.Single);headerParagraph.getFormat().getBorders().getBottom().setLineWidth(1f);//添加段落到頁腳Paragraph footerParagraph = footer.addParagraph();//添加Field_Page和Field_Num_Pages域到頁腳段落,用于顯示當前頁碼和總頁數footerParagraph.appendField("page number", FieldType.Field_Page);footerParagraph.appendText(" of ");footerParagraph.appendField("number of pages", FieldType.Field_Num_Pages);footerParagraph.getFormat().setHorizontalAlignment(HorizontalAlignment.Right);//設置頁腳段落的頂部邊線樣式footerParagraph.getFormat().getBorders().getTop().setBorderType(BorderStyle.Single);footerParagraph.getFormat().getBorders().getTop().setLineWidth(1f);}

highcharts轉svg插入html模板

 /**將highcharts生成<img>的src標簽插入html中方便pdf轉化**/function img() {$(".highchartImg").css("display","none");$.each($(".highchartImg"),function (idx,c) {var charData = $(this).highcharts().getSVG();var canvas = document.getElementById("canvas");canvg(canvas,charData);var image = new Image();image.src = canvas.toDataURL("image/png");$(this).next().attr("src",image.src);})}

設置highcharts原始和導出圖片大小

        chart: {zoomType: 'xy',  //圖片可拉伸type: 'column',width: 1200},exporting: {sourceWidth: 650,sourceHeight: 360,enabled: false,  //屏蔽下載圖片選擇框}

總結:html的元素標簽一定要注意規范性,否則樣式會有偏差,不過慢慢調試也能弄出來,比如一些表頭的格式偏差,rowspan=“0” 這種就不要顯示在標簽里了,默認就好。
好吧,先到這里。這只是個人一個階段性的總結和記錄,感謝很多提供思路的朋友,最終解決了問題。如果能幫到有同樣需求的伙伴就更好了。


該文章在 2023/5/15 12:22:22 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved