本次项目是把word pptx转为pdf以作在线浏览功能,如果有钱可以直接使用第三方国产jar不做转换直接使用即可。
exlce文档浏览暂且不发。因为多页的sheet会在本地测试中发生OOM,数据量太大。思路xlsx转html转图片 + 水印,可完整在线浏览出多页的sheet,前提不触发OOM
转pdf使用的是openOffice组件,在linux证实可以使用,以发生产环境。
使用openOffice代码块在此链接中
链接: https://blog.csdn.net/weixin_46551713/article/details/121290694
网页浏览pdf png 格式如下链接
链接: https://blog.csdn.net/weixin_46551713/article/details/121290868
依赖
<dependency>
<groupId>com.artofsolving</groupId>
<artifactId>jodconverter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.artofsolving.jodconverter</groupId>
<artifactId>jodconverter-core</artifactId>
<version>3.0-beta-4</version>
</dependency>
<dependency>
<groupId>juh</groupId>
<artifactId>juh</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>jurt</groupId>
<artifactId>jurt</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>ridl</groupId>
<artifactId>ridl</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>unoil</groupId>
<artifactId>unoil</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
xlsx以及xls加水印可设置文档不可编辑
public static void putWaterRemarkToExcel(Workbook wb, Sheet sheet, String waterRemarkPath, int startXCol,
int startYRow, int betweenXCol, int betweenYRow, int XCount, int YCount, int waterRemarkWidth,
int waterRemarkHeight, String name) throws IOException {
// 加载图片
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
BufferedImage bufferImg = ImageUtils.createWaterMark(name);
ImageIO.write(bufferImg, "png", byteArrayOut);
// 开始打水印
Drawing drawing = sheet.createDrawingPatriarch();
Drawing drawingPatriarch = sheet.getDrawingPatriarch();
for (int yCount = 0; yCount < YCount; yCount++) {
for (int xCount = 0; xCount < XCount; xCount++) {
int xIndexInteger = startXCol + (xCount * waterRemarkWidth) + (xCount * betweenXCol);
int yIndexInteger = startYRow + (yCount * waterRemarkHeight) + (yCount * betweenYRow);
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, xIndexInteger,
yIndexInteger, xIndexInteger + waterRemarkWidth, yIndexInteger + waterRemarkHeight);
Picture pic = drawing.createPicture(anchor,
wb.addPicture(byteArrayOut.toByteArray(), Workbook.PICTURE_TYPE_PNG));
pic.resize();
}
}
}
public static BufferedImage createWaterMark(String content) {
Integer width = 1000;
Integer height = 600;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获取bufferedImage对象
String fontType = "宋体";
Integer fontStyle = Font.PLAIN;
Integer fontSize = 50;
Font font = new Font(fontType, fontStyle, fontSize);
Graphics2D g2d = image.createGraphics(); // 获取Graphics2d对象
image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
g2d.dispose();
g2d = image.createGraphics();
g2d.setColor(Color.RED);
g2d.setColor(new Color(220, 0, 0, 60)); //设置字体颜色和透明度
g2d.setStroke(new BasicStroke(1)); // 设置字体
//g2d.setFont(font); // 设置字体类型 加粗 大小
g2d.setColor(new Color(255, 0, 0, 60)); //设置字体颜色和透明度
g2d.setStroke(new BasicStroke(1)); // 设置字体
g2d.setFont(font); // 设置字体类型 加粗 大小
g2d.rotate(Math.toRadians(-10), (double) image.getWidth() / 2, (double) image.getHeight() / 2);//设置倾斜度
FontRenderContext context = g2d.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(content, context);
double x = (width - bounds.getWidth()) / 2;
double y = (height - bounds.getHeight()) / 2;
double ascent = -bounds.getY();
double baseY = y + ascent;
// 写入水印文字原定高度过小,所以累计写水印,增加高度
g2d.drawString(content, (int) x, (int) baseY);
// 设置透明度
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
// 释放对象
g2d.dispose();
return image;
}
public static void main(String[] args) {
String filePath="全路径+文件名字";
String lastFileName = filePath.substring(filePath.lastIndexOf(".") + 1);
Workbook wb = null;
try {
if ("xlsx".equals(lastFileName)){
wb = new XSSFWorkbook(new FileInputStream(filePath));
}else if ("xls".equals(lastFileName)){
wb = new HSSFWorkbook(new FileInputStream(filePath));
}
int sheets = wb.getNumberOfSheets();
for (int i = 0; i < sheets; i++) {
Sheet sheet = wb.getSheetAt(i);
int row = sheet.getFirstRowNum() + sheet.getLastRowNum();
Row row1 = sheet.getRow(sheet.getFirstRowNum());
if (row1 == null) {
continue;
}
int cell = sheet.getRow(sheet.getFirstRowNum()).getLastCellNum() + 1;
putWaterRemarkToExcel(wb, sheet, null, 0, 0, 15, 15, cell / 15 + 1,
row / 15 + 1,
0,
0,
"水印内容~~~~~~~~~");
//TODO 设置的加密 密码
sheet.protectSheet(UUID.randomUUID().toString());
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
wb.write(os);
} catch (IOException e) {
e.printStackTrace();
}
wb.close();
byte[] content = os.toByteArray();
// Excel文件生成后存储的位置。
File excelPath = new File(filePath);
OutputStream fos = null;
try {
fos = new FileOutputStream(excelPath);
fos.write(content);
os.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
pdf加水印
public static void wateMark(InputStream inputStream, String outputFile, String tesName){
try{
PdfReader reader = new PdfReader(inputStream);
PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(outputFile));
BaseFont base = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.EMBEDDED);
com.itextpdf.text.Rectangle pageRect = null;
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.3f);
gs.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
FontMetrics metrics;
int textH = 0;
int textW = 0;
label.setText(tesName);
metrics = label.getFontMetrics(label.getFont());
textH = metrics.getHeight();
textW = metrics.stringWidth(label.getText());
PdfContentByte under;
for (int i = 1; i < total; i++) {
pageRect = reader.getPageSizeWithRotation(i);
under = stamper.getOverContent(i);
under.saveState();
under.setGState(gs);
under.beginText();
under.setFontAndSize(base, 20);
under.setRGBColorFill(145,145,145);
for (int height = interval + textH; height < pageRect.getHeight();
height = height + textH*3) {
for (int width = interval + textW; width < pageRect.getWidth() + textW;
width = width + textW*2) {
under.showTextAligned(Element.ALIGN_LEFT
, tesName, width - textW,
height - textH, 30);
}
}
under.endText();
}
stamper.close();
reader.close();
}catch (Exception e) {
e.printStackTrace();
}
}
jpg图片加水印
下面展示一些 内联代码片
。
public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
}
public static void setPictureWatermark(String srcImgPath ,String testName) {
FileOutputStream outImgStream = null;
try {
// 读取原图片信息
File srcImgFile = new File(new String(srcImgPath.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));
Image srcImg = ImageIO.read(srcImgFile);
int srcImgWidth = srcImg.getWidth(null);
int srcImgHeight = srcImg.getHeight(null);
// 加水印
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bufImg.createGraphics();
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
Font font = new Font("宋体", Font.PLAIN, srcImgHeight / 6);
g.setColor(Color.RED);
//设置旋转角度
g.rotate(Math.toRadians(-35), (double) bufImg.getWidth() / 2, (double) bufImg.getHeight() / 2);
//设置水印透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.4F));
g.setFont(font);
int x = (srcImgWidth - getWatermarkLength(testName , g)) / 2;
int y = srcImgHeight / 2;
g.drawString(testName, x, y);
g.dispose();
// 输出图片
outImgStream = new FileOutputStream(srcImgPath);
ImageIO.write(bufImg, "jpg", outImgStream);
outImgStream.flush();
outImgStream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (outImgStream != null) {
try {
outImgStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
png图片加水印
下面展示一些 内联代码片
。
//水印透明度
private static float alpha = 0.5f;
// 水印横向位置
private static int positionWidth = 250;
// 水印纵向位置
private static int positionHeight = 300;
// 水印文字字体
private static Font font = new Font("宋体", Font.BOLD, 72);
// 水印文字颜色
private static Color color = Color.red;
// degree 是水印的角度 -45 自己调
public void markImageByText(String testName, String srcImgPath, String targerPath, Integer degree) {
InputStream is = null;
OutputStream os = null;
try {
// 1、源图片
Image srcImg = ImageIO.read(new File(srcImgPath));
BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
// 2、得到画笔对象
Graphics2D g = buffImg.createGraphics();
// 3、设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(
srcImg.getScaledInstance(srcImg.getWidth(null),
srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
null);
// 4、设置水印旋转
if (null != degree) {
g.rotate(Math.toRadians(degree),
(double) buffImg.getWidth() / 2,
(double) buffImg.getHeight() / 2);
}
// 5、设置水印文字颜色
g.setColor(color);
// 6、设置水印文字Font
g.setFont(font);
// 7、设置水印文字透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
alpha));
// 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
g.drawString(testName, positionWidth, positionHeight);
// 9、释放资源
g.dispose();
// 10、生成图片
os = new FileOutputStream(targerPath);
ImageIO.write(buffImg, "png", os);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != is)
is.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (null != os)
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}