summary_rs/modify_docx/
mod.rs1use std::fs::File;
2use std::io::{Read, Write};
3use zip::write::{ExtendedFileOptions, FileOptions};
4use zip::{ZipArchive, ZipWriter};
5mod utils;
6use utils::*;
7
8type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
9
10pub fn modify_docx(input_path: &str, inspector: &str, width: f32, height: f32) -> Result<()> {
11 let mut file_content = Vec::new();
13 File::open(input_path)?.read_to_end(&mut file_content)?;
14
15 let mut archive = ZipArchive::new(std::io::Cursor::new(&file_content))?;
17
18 let mut output_buffer = Vec::new();
20 let mut zip_writer = ZipWriter::new(std::io::Cursor::new(&mut output_buffer));
21
22 for i in 0..archive.len() {
24 let mut file = archive.by_index(i)?;
25 let name = file.name().to_string();
26
27 if name == "word/document.xml" {
28 let mut content = String::new();
29 file.read_to_string(&mut content)?;
30 content = change_title(content);
31 content = change_test_info(content, inspector);
32 content = set_image_size(content, width, height)?;
33 content = set_image_behind_document(content)?;
34 content = set_page_margins(content)?;
35 zip_writer.start_file::<String, ExtendedFileOptions>(name, FileOptions::default())?;
37 zip_writer.write_all(content.as_bytes())?;
38 } else if name == "word/media/image1.png" {
39 let signature_path = match get_signature_path() {
40 Ok(path) => path,
41 Err(_) => {
42 println!("无法获取签名路径");
43 continue;
44 }
45 };
46 println!("signature_path: {}", signature_path);
47 let buffer = read_file_to_buffer(&signature_path)?;
48 zip_writer.start_file::<String, ExtendedFileOptions>(name, FileOptions::default())?;
49 zip_writer.write_all(&buffer)?;
50 } else {
51 let mut buffer = Vec::new();
52 file.read_to_end(&mut buffer)?;
53 zip_writer.start_file::<String, ExtendedFileOptions>(name, FileOptions::default())?;
54 zip_writer.write_all(&buffer)?;
55 }
56 }
57
58 zip_writer.finish()?;
59
60 let mut output_file = File::create(input_path)?;
62 match output_file.write_all(&output_buffer) {
63 Ok(_) => {
64 println!("修改成功");
65 }
66 Err(e) => {
67 println!("无法写入文件: {}", e);
68 }
69 };
70
71 Ok(())
72}
73
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use regex::Regex;
79
80 #[test]
81 fn test_modify_docx() {
82 let _ = modify_docx("0.docx", "test", 5.58, 1.73);
83 }
84
85 #[test]
86 fn test_replace_table_cell_width_with_const_string() {
87 let content = r#"签名Signatory</w:t></w:r></w:p><w:p w14:paraId="4FC9CFFB"><w:pPr><w:spacing w:line="280" w:lineRule="exact"/><w:jc w:val="center"/><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:szCs w:val="21"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:szCs w:val="21"/></w:rPr><w:t xml:space="preserve">职务 </w:t></w:r></w:p><w:p w14:paraId="0C3CBCD5"><w:pPr><w:spacing w:line="280" w:lineRule="exact"/><w:jc w:val="center"/><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:szCs w:val="21"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:szCs w:val="21"/></w:rPr><w:t>Title</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="3272" w:type="dxa"/><w:gridSpan w:val="3"/><w:tcBorders><w:top w:val="single" w:color="auto" w:sz="4" w:space="0"/><w:left w:val="single" w:color="auto" w:sz="4" w:space="0"/><w:bottom w:val="single" w:color="auto" w:sz="12" w:space="0"/><w:right w:val="single" w:color="auto" w:sz="4" w:space="0"/></w:tcBorders><w:vAlign w:val="center"/></w:tcPr><w:p w14:paraId="333CBBDC"><w:pPr><w:spacing w:line="280" w:lineRule="exact"/><w:jc w:val="center"/><w:rPr><w:rFonts w:eastAsia="华文行楷" w:cstheme="minorHAnsi"/><w:color w:val="auto"/><w:sz w:val="28"/><w:szCs w:val="28"/></w:rPr></w:pPr><w:r><w:drawing><wp:anchor distT="0" distB="0" distL="114300" distR="114300" simplePos="0" relativeHeight="251661312" behindDoc="1" locked="0" layoutInCell="1" allowOverlap="1"><wp:simplePos x="0" y="0"/><wp:positionH relativeFrom="column"><wp:posOffset>330835</wp:posOffset></wp:positionH><wp:positionV relativeFrom="paragraph"><wp:posOffset>22225</wp:posOffset></wp:positionV><wp:extent cx="2008800" cy="622800"/><wp:effectExtent l="0" t="0" r="18415" b="10795"/><wp:wrapNone/><wp:docPr id="2" name="图片 2"/><wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:nvPicPr><pic:cNvPr id="2" name="图片 2"/><pic:cNvPicPr><a:picLocks noChangeAspect="1"/></pic:cNvPicPr></pic:nvPicPr><pic:blipFill><a:blip r:embed="rId7"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="2008800" cy="622800"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom><a:noFill/><a:ln><a:noFill/></a:ln></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:anchor></w:drawing></w:r></w:p><w:p w14:paraId="4EAAA74E"><w:pPr><w:spacing w:line="280" w:lineRule="exact"/><w:jc w:val="center"/><w:rPr><w:rFonts w:eastAsia="华文行楷" w:cstheme="minorHAnsi"/><w:color w:val="auto"/><w:sz w:val="28"/><w:szCs w:val="28"/></w:rPr></w:pPr></w:p><w:p w14:paraId="257FBBF8"><w:pPr><w:spacing w:line="280" w:lineRule="exact"/><w:jc w:val="center"/><w:rPr><w:rFonts w:eastAsia="华文行楷" w:cstheme="minorHAnsi"/><w:color w:val="auto"/><w:sz w:val="28"/><w:szCs w:val="28"/></w:rPr></w:pPr></w:p><w:p w14:paraId="66BC216D"><w:pPr><w:spacing w:line="280" w:lineRule="exact"/><w:jc w:val="center"/><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:szCs w:val="21"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:color w:val="auto"/><w:szCs w:val="21"/></w:rPr><w:t>检验员Inspector:test</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="1335" w:type="dxa"/><w:gridSpan w:val="2"/><w:tcBorders><w:top w:val="single" w:color="auto" w:sz="4" w:space="0"/><w:left w:val="single" w:color="auto" w:sz="4" w:space="0"/><w:bottom w:val="single" w:color="auto" w:sz="12" w:space="0"/><w:right w:val="single" w:color="auto" w:sz="4" w:space="0"/></w:tcBorders><w:vAlign w:val="center"/></w:tcPr><w:p w14:paraId="7750C236"><w:pPr><w:widowControl/><w:spacing w:line="280" w:lineRule="exact"/><w:jc w:val="center"/><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:color w:val="auto"/><w:szCs w:val="21"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:color w:val="auto"/><w:szCs w:val="21"/></w:rPr><w:t>签发日期</w:t></w:r></w:p><w:p w14:paraId="47FC4B05"><w:pPr><w:spacing w:line="280" w:lineRule="exact"/><w:jc w:val="center"/><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:szCs w:val="21"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:color w:val="auto"/><w:szCs w:val="21"/></w:rPr><w:t>Issued Date</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="3686" w:type="dxa"/><w:gridSpan w:val="5"/><w:tcBorders><w:top w:val="single" w:color="auto" w:sz="4" w:space="0"/><w:left w:val="single" w:color="auto" w:sz="4" w:space="0"/><w:bottom w:val="single" w:color="auto" w:sz="12" w:space="0"/><w:right w:val="single" w:color="auto" w:sz="12" w:space="0"/></w:tcBorders><w:vAlign w:val="center"/></w:tcPr><w:sdt><w:sdtPr><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:color w:val="auto"/><w:szCs w:val="21"/></w:rPr><w:id w:val="147467335"/><w:placeholder><w:docPart w:val="{63add1fe-0aab-4e4c-ba56-35791ee4bace}"/></w:placeholder><w:date w:fullDate="2024-10-30T00:00:00Z"><w:dateFormat w:val="yyyy-MM-dd"/><w:lid w:val="en-US"/><w:storeMappedDataAs w:val="datetime"/><w:calendar w:val="gregorian"/></w:date></w:sdtPr><w:sdtEndPr><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:color w:val="auto"/><w:szCs w:val="21"/></w:rPr></w:sdtEndPr><w:sdtContent><w:p w14:paraId="53F3CEBE"><w:pPr><w:spacing w:line="280" w:lineRule="exact"/><w:jc w:val="center"/><w:rPr><w:rFonts w:cstheme="minorHAnsi"/><w:color w:val="auto"/><w:szCs w:val="21"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:asciiTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:eastAsiaTheme="minorEastAsia" w:cstheme="minorHAnsi"/><w:color w:val="auto"/><w:kern w:val="2"/><w:sz w:val="21"/><w:szCs w:val="21"/><w:lang w:val="en-US" w:eastAsia="zh-CN" w:bidi="ar-SA"/></w:rPr><w:t>2024-10-31</w:t></w:r></w:p></w:sdtContent></w:sdt></w:tc></w:tr></w:tbl><w:p w14:paraId="6B74A4C4"><w:pPr><w:spacing w:line="280" w:lineRule="exact"/><w:rPr><w:color w:val="000000" w:themeColor="text1"/><w:szCs w:val="21"/></w:rPr></w:pPr></w:p><w:sectPr><w:headerReference r:id="rId5" w:type="first"/><w:headerReference r:id="rId3" w:type="default"/><w:headerReference r:id="rId4" w:type="even"/><w:pgSz w:w="11906" w:h="16838"/><w:pgMar w:top="1134" w:right="1230" w:bottom="567" w:left="1230" w:header="851" w:footer="992" w:gutter="0"/><w:cols w:space="425" w:num="1"/><w:docGrid w:type="lines" w:linePitch="312" w:charSpace="0"/></w:sectPr></w:body></w:document>"#;
88 let re = Regex::new(r#"w:tcW w:w="1335"\sw:type="dxa""#).unwrap();
89 let new_content = re.replace(content, "B0599DDA0D5649F4ACB5432F7C4003461").to_string();
90 println!("{}", new_content);
91 }
92
93 #[test]
94 fn test_set_specific_table_cell_width() {
95 let text = "我有2个苹果和3个橘子。";
96 let re = Regex::new(r"\d+").unwrap(); let result = re.replace(text, "X"); println!("{}", result); }
103}