电子档案目录PDF预览

# 需求
档案电子化  著录模块  需要PDF预览功能  方便打印标准A4纸质文档
模版如下图:

代码流程:

 控制层:

	/**
	 * 预览档案目录
	 */
	@GetMapping("preview-category")
	@ApiOperationSupport(order = 12)
	@ApiOperation(value = "预览档案目录", notes = "传入documInfoId")
	public void previewCategory(@ApiIgnore @RequestParam Long documInfoId, HttpServletResponse response) throws Exception {
		documCategoryService.previewCategory(documInfoId, response);

 	}

 实现:

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void previewCategory(Long documInfoId, HttpServletResponse response) throws Exception
	{
		//获取通用模版数据
		List<DocumCategoryVO> documCategoryList = baseMapper.exportCategory();

		//获取所有子集
		documCategoryList = this.getChildren(documCategoryList, documInfoId);

		//查询档案 信息
		DocumInfo documInfo = documInfoService.getBaseMapper().selectById(documInfoId);
		//转化为easyExcel数据
		List<CategoryExcel> categoryExcels = this.change(documCategoryList);
		//excel转pdf
		changeToPdf(categoryExcels, documInfo, response);
	}

技术1:

easyExcel

EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。

文档:EasyExcel · 语雀

先写model及配置

package org.springblade.modules.document.excel;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.*;
import com.aspose.cells.Color;
import com.aspose.cells.Style;
import lombok.Data;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.xwpf.usermodel.Borders;

import java.io.Serializable;

/**
 *
 * @author zhq
 */
@Data
@ColumnWidth(30)
@HeadStyle(borderLeft = BorderStyle.THIN,borderBottom = BorderStyle.THIN,borderRight = BorderStyle.THIN,borderTop = BorderStyle.THIN,fillBackgroundColor = 5)
//@HeadFontStyle(fontHeightInPoints = 12)
@HeadRowHeight(20)
@ContentRowHeight(30)
//@ContentFontStyle(fontName = "宋体")
@ContentStyle(borderLeft = BorderStyle.THIN,borderBottom = BorderStyle.THIN,
	borderRight = BorderStyle.THIN,borderTop = BorderStyle.THIN,horizontalAlignment = HorizontalAlignment.CENTER)
public class CategoryExcel implements Serializable {
	private static final long serialVersionUID = 1L;

	@ColumnWidth(8)
	@ExcelProperty(value = "序号",index = 0)
	private String serialNumber;

	@ColumnWidth(33)
	@ExcelProperty(value = "材料名称",index = 1)
	private String name;

	@ColumnWidth(8)
	@ExcelProperty(value = {"材料形成时间","年"},index = 2)
	private String year;

	@ColumnWidth(8)
	@ExcelProperty(value = {"材料形成时间","月"},index = 3)
	private String month;

	@ColumnWidth(8)
	@ExcelProperty(value = {"材料形成时间","日"},index = 4)
	private String day;

	@ColumnWidth(8)
	@ExcelProperty(value = "页数",index = 5)
	private String pageNum;

	@ColumnWidth(8)
	@ExcelProperty(value = "备注",index = 6)
	private String remark;
}

 easyExcel数据转化

@Override
	public void changeToPdf(List<CategoryExcel> categoryExcels, DocumInfo documInfo, HttpServletResponse response) throws Exception
	{
		String execlName = System.getProperty("user.dir") + File.separator + UUID.randomUUID() + ".xlsx";
		String pdfName = System.getProperty("user.dir") + File.separator + UUID.randomUUID() + ".pdf";

		ClassPathResource classPathResource = new ClassPathResource("templates/category.xlsx");

		int index = 1;
		int size = categoryExcels.size();
		int total = (int) Math.ceil((double) size / 20);
		//ExcelWriter excelWriter = EasyExcel.write(execlName).withTemplate(templateFileName).build();

		XSSFWorkbook workbook = new XSSFWorkbook(classPathResource.getInputStream());
		// 复制你数据的N-1条,本来第0个sheet有一条
		for (int i = 0; i < total; i++)
		{
			workbook.cloneSheet(0);
		}
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		workbook.write(bos);
		byte[] bArray = bos.toByteArray();
		InputStream is = new ByteArrayInputStream(bArray);

		ExcelWriter excelWriter = EasyExcel.write(execlName).withTemplate(is).build();

		for (int i = 1; i < total + 1; i++)
		{
			WriteSheet writeSheet = EasyExcel.writerSheet(i - 1, "Sheet" + (i - 1)).build();
			List<CategoryExcel> data = new ArrayList<>();
            //每页20条数据处理
			if (i == total)
			{
				data = categoryExcels.subList(20 * (i - 1), size);
				//填充空的数据
				for (int j = size; j < 20 * i; j++)
				{
					data.add(new CategoryExcel());
				}
			} else
			{
				data = categoryExcels.subList(20 * (i - 1), 20 * i);
			}
			excelWriter.fill(data, writeSheet);
            //填充模版里的第几页  总页数   材料名称  档案编号
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("document_no", documInfo.getDocumentNo());
			map.put("name", documInfo.getName());
			map.put("index", i);
			map.put("total", total);
			excelWriter.fill(map, writeSheet);
		}
		excelWriter.finish();


		Excel2PDF.excel2pdf(execlName, pdfName, total);
		documPageService.execl(pdfName, response);

	}

转pdf 

用到apose-cells 8.5.2jar包

apose官网链接:File Format APIs for Word Excel PDF Email PowerPoint Barcode Images OCR Note &amp; 3D

package org.springblade.modules.document.excel;

import com.aspose.cells.License;
import com.aspose.cells.PdfSaveOptions;
import com.aspose.cells.Workbook;
import com.aspose.cells.Worksheet;
import com.lowagie.text.pdf.PdfPage;
import com.lowagie.text.pdf.PdfPageEvent;
import com.lowagie.text.pdf.PdfPages;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

public class Excel2PDF {

    /**
     * 获取license 去除水印
     * @return
     */
    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = Excel2PDF.class.getClassLoader().getResourceAsStream("\\templates\\license.xml");
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * excel 转为pdf 输出。
     *
     * @param sourceFilePath  excel文件
     * @param desFilePathd  pad 输出文件目录
     */
    public static void excel2pdf(String sourceFilePath, String desFilePathd,int total) throws Exception{
        if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
            return;
        }
        try {
            Workbook wb = new Workbook(sourceFilePath);// 原始excel路径

            FileOutputStream fileOS = new FileOutputStream(desFilePathd);
            PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
			pdfSaveOptions.setDefaultFont("宋体");
			pdfSaveOptions.setOnePagePerSheet(true);

            //int[] autoDrawSheets={3};
            //当excel中对应的sheet页宽度太大时,在PDF中会拆断并分页。此处等比缩放。
            autoDraw(wb,total);

            //int[] showSheets={total};
            //隐藏workbook中不需要的sheet页。
            printSheetPage(wb,total);
            wb.save(fileOS, pdfSaveOptions);
            fileOS.flush();
            fileOS.close();
        } finally {
			File execlFile = new File(sourceFilePath);
			if (execlFile != null&&execlFile.exists())
			{
				execlFile.delete();
			}
		}
    }


    /**
     * 设置打印的sheet 自动拉伸比例
     * @param wb
     * @param page 自动拉伸的页的sheet数组
     */
    public static void autoDraw(Workbook wb,int total){
        if(total>0){
            for (int i = 0; i < total; i++) {
                wb.getWorksheets().get(i).getHorizontalPageBreaks().clear();
                wb.getWorksheets().get(i).getVerticalPageBreaks().clear();
            }
        }
    }


    /**
     * 隐藏workbook中不需要的sheet页。
     * @param wb
     * @param page 显示页的sheet数组
     */
    public static void printSheetPage(Workbook wb,int total){
        for (int i= 1; i < wb.getWorksheets().getCount(); i++)  {
            wb.getWorksheets().get(i).setVisible(false);
        }
        if(total==0){
            wb.getWorksheets().get(0).setVisible(true);
        }else{
            for (int i = 0; i < total; i++) {
                wb.getWorksheets().get(i).setVisible(true);
            }
        }
    }

}


使用的模版文件:

结果:

 难点1:

模版复制多个sheet页   easyexcel没提供   在下面评论给出的方案

// 模板地址
String templateFileName = BugReportDocServiceImplTest.class.getResource("/static/excel/sectionBugDetailListTemplate.xlsx").getPath();
// 从数据库获取并封装数据
List<SectionCheckExcelBO> sectionCheckExcelByLineId = bugReportDocService.findSectionCheckExcelByLineId(71L);
LocalDateTime localDateTime = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HHmmss");
// 复制N个sheet的输出文件
String fileName = "d:/temp/abc"+dateTimeFormatter.format(localDateTime)+".xlsx";

  // 复制模板
File tempFile = new File(templateFileName);
FileInputStream fis = new FileInputStream(tempFile);
XSSFWorkbook workbook = new XSSFWorkbook(fis);
// 复制你数据的N-1条,本来第0个sheet有一条
for (int i = 0; i < sectionCheckExcelByLineId.size() -1 ; i++) {
	workbook.cloneSheet(0);
}
FileOutputStream out = new FileOutputStream(new File(fileName));
out.flush();
workbook.write(out);
out.close();
// 最后要输出的多sheet文件路径
String writeFile = "d:/temp/Write"+dateTimeFormatter.format(localDateTime)+".xlsx";
// easyexcel模板输出
	ExcelWriter excelWriter = EasyExcel.write(writeFile).withTemplate(fileName).build();
	for (int i = 0; i < sectionCheckExcelByLineId.size(); i++) {
		WriteSheet sheet = EasyExcel.writerSheet().build();
		sheet.setSheetNo(i);
		sheet.setSheetName("Sheet" + (i+1));
		SectionCheckExcelBO bo = sectionCheckExcelByLineId.get(i);
		System.out.println(JsonFormatUtil.formatJson(new Gson().toJson(bo)));
		excelWriter.fill(bo, sheet);
		FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
		excelWriter.fill(bo.getBugExcelBOList(), fillConfig, sheet);
	}
excelWriter.finish();
// 中心思想就是:通过poi把模板复制N条数据对应的N个模板sheet, 然后用easyexcel来输出
// 有种曲线救国的意思,poi容易oom,相对于XSSFWorkbook优化后的SXSSFWorkbook又不支持克隆
// 数据量大的话够呛

难点2:

apose不熟悉

PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
			pdfSaveOptions.setDefaultFont("宋体");
			pdfSaveOptions.setOnePagePerSheet(true);

            //int[] autoDrawSheets={3};
            //当excel中对应的sheet页宽度太大时,在PDF中会拆断并分页。此处等比缩放。
            autoDraw(wb,total);

            //int[] showSheets={total};
            //隐藏workbook中不需要的sheet页。
            printSheetPage(wb,total);

pdf只有单页  表头乱跑问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在uniapp小程序中实现PDF预览功能,可以采用以下方法。首先,你可以使用web-view组件来装载远程的viewer.html页面,该页面使用pdf.js库来解析和显示PDF文件。这样可以实现基本的预览功能。然而,如果你想要实现手指缩放功能,你可能需要使用其他的解决方案。 一个简单的解决方案是使用uni.downloadFile方法下载PDF文件到本地,然后使用uni.openDocument方法打开该文件。你可以通过后端接口获取PDF文件的URL,并将其作为参数传递给uni.downloadFile方法。下载成功后,你可以使用uni.openDocument方法打开该文件,并指定文件类型为PDF。这样就可以在小程序中实现PDF预览功能,并且支持手指缩放。\[3\] 以下是一个示例代码: ```javascript uni.downloadFile({ url: 'http://example.com/path/to/pdf', // 替换为你的PDF文件URL success: function (res) { var filePath = res.tempFilePath; uni.openDocument({ filePath: filePath, fileType: 'pdf', success: function (res) { console.log('打开文档成功'); uni.hideLoading(); } }); } }); ``` 请注意,你需要将URL替换为你实际的PDF文件URL。这个方法可以在uniapp小程序中实现PDF预览功能,并且支持手指缩放。希望对你有帮助! #### 引用[.reference_title] - *1* *3* [关于使用uniapp在小程序中预览pdf文件可手势缩放的至简方案](https://blog.csdn.net/VastWu/article/details/107663315)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [uni-app 小程序使用 web-view实现在线预览dpf,及H5电子签字](https://blog.csdn.net/zhang0609/article/details/107983830)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值