using Xceed.Document.NET;
using Xceed.Words.NET;
public static void Test()
{
string docxPath = @"D:\test.docx";
string imagePath = @"D:\test.jpg";
using (DocX document = DocX.Create(docxPath))
{
var image = document.AddImage(imagePath);
var picture = image.CreatePicture(400, 300);
document.InsertParagraph()
.AppendPicture(picture)
.Alignment = Alignment.center;
document.Save();
}
}
DocX 문서를 생성하여 저장했습니다.
MsWord 로 열면 이미지가 정상으로 보입니다.
한컴워드로 열면 이미지가 엑박 표시되는데
MsWord에서 다른이름으로 저장하면 데이터 일부 소실된다고 메시지 발생하고,
한컴워드로 열면 제대로 보이네요.
ChatGPT, Gemini 모두 해결이 안되고 있습니다.
무엇을 놓치고 있는 것일까요?
개발환경: VS2026, C#, 한컴오피스 2014, 2024
고맙습니다.~
안녕하세요
.docx의 관계 파일(word/_rels/document.xml.rels)에서 이미지 Target이 절대 경로로 되어 있어서 한워드에서 이미지가 안 보였던 것 같습니다. document.Save(); 를 한 이후에 상대 경로로 변경하는 작업을 해야 할 것 같습니다. 아래 코드 참고하시면 좋을 것 같습니다.
using System.IO.Compression;
using System.Xml.Linq;
// 저장 직후 호출: 관계 Target 절대경로 -> 상대경로
static void MakeRelationshipTargetsRelative(string docxPath)
{
XNamespace ns = "http://schemas.openxmlformats.org/package/2006/relationships";
using var zip = ZipFile.Open(docxPath, ZipArchiveMode.Update);
foreach (var entry in zip.Entries
.Where(e => e.FullName.EndsWith(".rels", StringComparison.OrdinalIgnoreCase))
.ToList())
{
int i = entry.FullName.LastIndexOf("_rels/", StringComparison.OrdinalIgnoreCase);
string baseDir = i <= 0 ? "" : entry.FullName.Substring(0, i); // "word/_rels/..." -> "word/"
XDocument doc;
using (var s = entry.Open()) doc = XDocument.Load(s);
bool changed = false;
foreach (var r in doc.Root!.Elements(ns + "Relationship"))
{
if (string.Equals((string?)r.Attribute("TargetMode"), "External", StringComparison.OrdinalIgnoreCase))
continue;
var target = (string?)r.Attribute("Target");
if (string.IsNullOrEmpty(target) || target[0] != '/') continue;
r.SetAttributeValue("Target", ToRelative(baseDir, target.Substring(1)));
changed = true;
}
if (!changed) continue;
using var s2 = entry.Open();
s2.SetLength(0);
using var w = new StreamWriter(s2, new UTF8Encoding(false));
doc.Save(w);
}
}
static string ToRelative(string baseDir, string abs)
{
var b = baseDir.Split('/', StringSplitOptions.RemoveEmptyEntries);
var t = abs.Split('/');
int k = 0;
while (k < b.Length && k < t.Length - 1 &&
string.Equals(b[k], t[k], StringComparison.OrdinalIgnoreCase)) k++;
var parts = new List<string>();
for (int j = k; j < b.Length; j++) parts.Add("..");
for (int j = k; j < t.Length; j++) parts.Add(t[j]);
return string.Join("/", parts);
}
using (DocX document = DocX.Create(docxPath))
{
var image = document.AddImage(imagePath);
var picture = image.CreatePicture(300, 400);
document.InsertParagraph()
.AppendPicture(picture)
.Alignment = Alignment.center;
document.Save();
}
MakeRelationshipTargetsRelative(docxPath); // ★ 이 한 줄
저희도 한워드 쪽은 잘 모르기 때문에
한워드에 관한 추가 문의 사항은 고객지원센터에 문의하시면 좋을 것 같습니다.
감사합니다.